Wdrażam funkcję śledzenia, które artykuły użytkownik przeczytał.
create_table "article", :force => true do |t|
t.string "title"
t.text "content"
end
To jest moja dotychczasowa migracja:
create_table :user_views do |t|
t.integer :user_id
t.integer :article_id
end
Tabela user_views będzie zawsze przeszukiwana w celu wyszukania obu kolumn, a nie tylko jednej. Moje pytanie brzmi, jak powinien wyglądać mój indeks. Czy istnieje różnica w kolejności tych tabel, czy powinno być więcej opcji, czy cokolwiek innego. Moja docelowa baza danych to Postgres.
add_index(:user_views, [:article_id, :user_id])
Dzięki.
AKTUALIZACJA:
Ponieważ może istnieć tylko jeden wiersz zawierający te same wartości w obu kolumnach (ponieważ wiedząc, czy identyfikator_użytkownika przeczytał article_id), czy powinienem rozważyć opcję: unique? Jeśli się nie mylę, oznacza to, że nie muszę samodzielnie sprawdzać i po prostu wstawiać wstawkę za każdym razem, gdy użytkownik odwiedza artykuł.
źródło
Odpowiedzi:
Kolejność ma znaczenie w indeksowaniu.
[:user_id, :article_id]
, możesz wykonać szybkie zapytanie nauser_id
lubuser_id AND article_id
, ale NIE naarticle_id
.Twoja
add_index
linia migracji powinna wyglądać mniej więcej tak:Pytanie dotyczące opcji „unikalnej”
Prostym sposobem na zrobienie tego w Railsach jest użycie
validates
w swoim modelu zuniqueness
następującym zakresem ( dokumentacja ):źródło
validates_uniqueness_of
(i jego kuzynvalidates uniqueness:
) są podatni na warunki wyściguTylko ostrzeżenie o sprawdzaniu unikalności w czasie walidacji w porównaniu z indeksem: to drugie jest wykonywane przez bazę danych, podczas gdy elementarz jest wykonywany przez model. Ponieważ może istnieć kilka jednoczesnych wystąpień modelu działającego w tym samym czasie, walidacja podlega warunkom wyścigu, co oznacza, że w niektórych przypadkach może nie wykryć duplikatów (np. Przesłać dwukrotnie ten sam formularz w tym samym czasie).
źródło