Index on multiple columns in Ruby on Rails
Solution 1:
The order does matter in indexing.
- Put the most selective field first, i.e. the field that narrows down the number of rows fastest.
- The index will only be used insofar as you use its columns in sequence starting at the beginning. i.e. if you index on
[:user_id, :article_id]
, you can perform a fast query onuser_id
oruser_id AND article_id
, but NOT onarticle_id
.
Your migration add_index
line should look something like this:
add_index :user_views, [:user_id, :article_id]
Question regarding 'unique' option
An easy way to do this in Rails is to use validates
in your model with scoped uniqueness
as follows (documentation):
validates :user, uniqueness: { scope: :article }
Solution 2:
Just a warning about checking uniqueness at validation time vs. on index: the latter is done by database while the primer is done by the model. Since there might be several concurrent instances of a model running at the same time, the validation is subject to race conditions, which means it might fail to detect duplicates in some cases (eg. submit twice the same form at the exact same time).