Frage

Angenommen, Sie haben zwei Modelle, Benutzer und Stadt, durch ein drittes Modell CityPermission verbunden:

class CityPermission < ActiveRecord::Base
  belongs_to :city
  belongs_to :user
end

class City < ActiveRecord::Base
  has_many :city_permissions
  has_many :users, :through => :city_permissions
end

class User < ActiveRecord::Base
  has_many :city_permissions
  has_many :cities, :through => :city_permissions
end

Derzeit erstelle ich den Tisch kommen, und den Index für die Tabelle, den folgenden Migration Codeausschnitt mit:

create_table :city_permissions do |t|
      t.integer :user_id, :city_id
      t.other_fields ...
end

add_index(:city_permissions, :user_id)
add_index(:city_permissions, :city_id)

Sind diese die optimalen Indizes zu erstellen? Werden diese Indizes ermöglichen den schnellen Zugriff hin und her durch den Tisch kommen, sowie schnelle Lookups in der Tabelle selbst, oder gibt es eine andere Art und Weise besser? Neu zu formulieren anders dieses ein wenig, werden diese Indizes gegeben city und user sind Instanzvariablen der Klasse City und Benutzer erlauben city.users, city.city_permissions, user.cities und user.city_permissions allen gleichermaßen gut durchführen?

War es hilfreich?

Lösung

Sieht gut aus für mich.

Das schließt sich gerade erzeugte sollte entweder der PK-IDs der Einheit Tabellen oder auf dem FK-IDs in der Join-Tabelle auf sein -., Die beide Indizes

Wahrscheinlich an der generierten SQL Active aussehen würde gut sein, und vergleichen Sie sie gegen die Indizes.

Abhängig davon, welche Datenbank Sie sind auf Sie dann, dass SQL über einen Plan ausführen könnte erklären (oder was auch immer Werkzeug vorhanden ist, ich denke, Oracle hier)

Ihr Code zu vereinfachen, können Sie mit Blick has_and_belongs_to_many als auch. Das würde man loswerden der CityPermission Objekt erhalten lassen

(es sei denn, dass Sie das Speichern von Daten in sich selbst verwenden möchten)

Andere Tipps

Hier ist die SQL, die Activerecord für user.cities erzeugt:

SELECT `cities`.* FROM `cities` INNER JOIN city_permissions ON (cities.id = city_permissions.city_id) WHERE (city_permissions.user_id = 1 )

EXPLAIN Ergebnisse unter:

+----+-------------+------------------+--------+---------------------------------------------------------------------+-----------------------------------+---------+-------------------------------------------------+------+-------------+
| id | select_type | table            | type   | possible_keys                                                       | key                               | key_len | ref                                             | rows | Extra       |
+----+-------------+------------------+--------+---------------------------------------------------------------------+-----------------------------------+---------+-------------------------------------------------+------+-------------+
|  1 | SIMPLE      | city_permissions | ref    | index_city_permissions_on_user_id,index_city_permissions_on_city_id | index_city_permissions_on_user_id | 5       | const                                           |    1 | Using where |
|  1 | SIMPLE      | cities           | eq_ref | PRIMARY                                                             | PRIMARY                           | 4       | barhopolis_development.city_permissions.city_id |    1 |             |
+----+-------------+------------------+--------+---------------------------------------------------------------------+-----------------------------------+---------+-------------------------------------------------+------+-------------+

Und hier ist die SQL, die Activerecord für user.city_permissions erzeugt:

SELECT * FROM `city_permissions` WHERE (`city_permissions`.user_id = 1)

Mit den EXPLAIN Ergebnisse für die Abfrage:

+----+-------------+------------------+------+-----------------------------------+-----------------------------------+---------+-------+------+-------------+
| id | select_type | table            | type | possible_keys                     | key                               | key_len | ref   | rows | Extra       |
+----+-------------+------------------+------+-----------------------------------+-----------------------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | city_permissions | ref  | index_city_permissions_on_user_id | index_city_permissions_on_user_id | 5       | const |    1 | Using where |
+----+-------------+------------------+------+-----------------------------------+-----------------------------------+---------+-------+------+-------------+

Sieht aus wie es in der Tat richtig funktioniert . Aus dem MySQL-Handbuch:

eq_ref

Eine Zeile aus dieser Tabelle für jede Kombination von Zeilen aus den vorherigen Tabellen lesen. Anders als das System und const Typen ist dies die bestmögliche Art verbinden. Es wird verwendet, wenn alle Teile eines Index durch die Verknüpfung verwendet werden und der Index ein Primärschlüssel oder eindeutiger Index.

ref

Alle Zeilen mit passenden Indexwerten werden aus dieser Tabelle für jede Kombination von Zeilen aus den vorherigen Tabellen lesen. ref verwendet wird, der nur einen linken Präfix des Schlüssels oder wenn der Schlüssel nicht ein PRIMARY KEY oder ein eindeutiger Index, wenn Join verwendet (in anderen Worten, wenn die Verbindung nicht eine einzige Zeile auf dem Grundlage des Schlüsselwert auswählen). Wenn der Schlüssel, der nur ein paar Zeilen Spiele verwendet wird, ist dies ein guter Typ verbinden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top