J'implémente une fonctionnalité pour suivre les articles lus par un utilisateur.
create_table "article", :force => true do |t|
t.string "title"
t.text "content"
end
Voici ma migration jusqu'à présent:
create_table :user_views do |t|
t.integer :user_id
t.integer :article_id
end
La table user_views sera toujours interrogée pour rechercher les deux colonnes, jamais une seule. Ma question est de savoir à quoi devrait ressembler mon index. Y a-t-il une différence dans l'ordre de ces tableaux, devrait-il y avoir d'autres options ou quoi que ce soit. Ma base de données cible est Postgres.
add_index(:user_views, [:article_id, :user_id])
Merci.
MISE À JOUR:
Puisqu'une seule ligne contenant les mêmes valeurs dans les deux colonnes peut exister (car en sachant si user_id A lu article_id), devrais-je considérer l'option: unique? Si je ne me trompe pas, cela signifie que je n'ai pas à faire de vérification par moi-même et simplement à faire un encart à chaque fois qu'un utilisateur visite un article.
L'ordre importe dans l'indexation.
[:user_id, :article_id]
, vous pouvez effectuer une requête rapide sur user_id
ou user_id AND article_id
, mais PAS le article_id
.Votre migration add_index
la ligne devrait ressembler à ceci:
add_index :user_views, [:user_id, :article_id]
Un moyen simple de le faire dans Rails est d'utiliser validates
dans votre modèle avec la portée uniqueness
comme suit ( documentation ):
validates :user, uniqueness: { scope: :article }
Juste un avertissement sur la vérification de l'unicité au moment de la validation par rapport à l'index: cette dernière est effectuée par la base de données tandis que l'amorce est effectuée par le modèle. Étant donné qu'il peut y avoir plusieurs instances simultanées d'un modèle en cours d'exécution en même temps, la validation est soumise à des conditions de concurrence critique, ce qui signifie qu'il peut ne pas détecter les doublons dans certains cas (par exemple, soumettre deux fois le même formulaire en même temps).