Я реализую функцию отслеживания статей, прочитанных пользователем.
create_table "article", :force => true do |t|
t.string "title"
t.text "content"
end
Это моя миграция:
create_table :user_views do |t|
t.integer :user_id
t.integer :article_id
end
Таблица user_views всегда будет запрашивать оба столбца, а не только один. Мой вопрос в том, как должен выглядеть мой индекс. Есть ли разница в порядке этих таблиц, должны ли быть какие-то дополнительные опции или что-то еще? Моя целевая БД - Postgres.
add_index(:user_views, [:article_id, :user_id])
Спасибо.
ОБНОВЛЕНИЕ:
поскольку может существовать только одна строка, содержащая одинаковые значения в обоих столбцах (поскольку, зная, читал ли user_id article_id), следует ли мне рассмотреть вариант: unique? Если я не ошибаюсь, это означает, что мне не нужно делать никаких проверок самостоятельно и просто делать вставку каждый раз, когда пользователь посещает статью.
ruby-on-rails
ruby-on-rails-3
database-design
indexing
Эмиль Альбек
источник
источник
Ответы:
Порядок имеет значение при индексации.
[:user_id, :article_id]
, вы можете выполнить быстрый запрос наuser_id
илиuser_id AND article_id
, но НЕ наarticle_id
.Ваша
add_index
линия миграции должна выглядеть примерно так:Вопрос относительно «уникального» варианта
Самый простой способ сделать это в Rails - использовать
validates
в вашей модели со следующей областью видимостиuniqueness
( документация ):источник
validates_uniqueness_of
(и его двоюродный братvalidates uniqueness:
) склонны к условиям гонкиПросто предупреждение о проверке уникальности во время проверки по сравнению с индексом: последняя выполняется базой данных, а праймер - моделью. Поскольку может быть несколько одновременных экземпляров модели, работающих одновременно, проверка зависит от условий гонки, что означает, что в некоторых случаях может не обнаружиться дубликатов (например, отправить дважды одну и ту же форму в одно и то же время).
источник