web-dev-qa-db-fra.com

Index sur plusieurs colonnes en Ruby on Rails

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.

84
Emil Ahlbäck

L'ordre importe dans l'indexation.

  1. Mettez le champ le plus sélectif en premier, c'est-à-dire le champ qui réduit le plus rapidement le nombre de lignes.
  2. L'index ne sera utilisé que dans la mesure où vous utilisez ses colonnes dans l'ordre à partir du début. c'est-à-dire si vous indexez sur [: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]

Question concernant l'option "unique"

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 }
188
sscirrus

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).

21
olivier