Fermer - vous souhaitez probablement ce qui suit :
add_index :person_products, [:person_id, :product_id], :unique => true
add_index :person_products, :product_id
Le :unique => true
n'est pas strictement nécessaire et cela dépend s'il est logique ou non d'avoir une personne associée à un produit plusieurs fois. Je dirais que si vous n'êtes pas sûr, vous probablement veux le :unique
drapeau.
La raison de la structure de l'index est que toutes les bases de données modernes peuvent exécuter des requêtes sur person_id et product_id en utilisant le premier index quel que soit l'ordre spécifié dans une requête . Par exemple
SELECT foo FROM bar WHERE person_id = 1 AND product_id = 2
SELECT foo FROM bar WHERE product_id = 2 AND person_id = 1
sont traités de la même manière et la base de données est suffisamment intelligente pour utiliser le premier index.
De même, les requêtes utilisant uniquement person_id
peut également être exécuté en utilisant le premier index. Les index b-tree multi-colonnes peuvent utiliser moins de colonnes qu'ils n'en ont à condition qu'ils soient spécifiés à partir de la gauche de la déclaration d'origine.
Pour les requêtes utilisant uniquement product_id
, cela ne peut pas être exécuté sur le premier index (puisque cet index est défini avec person_id dans la position la plus à gauche). Par conséquent, vous avez besoin d'un index séparé pour activer les recherches sur ce champ uniquement.
La propriété d'index multi-colonnes b-tree s'étend également aux index avec un plus grand nombre de colonnes. Si vous aviez un index sur (person_id, product_id, favorite_color, shirt_size)
, vous pouvez utiliser cet index pour exécuter des requêtes à l'aide de person_id
, (person_id, product_id)
, etc, tant que l'ordre correspond à la définition.