Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Index on multiple columns in Ruby on Rails

I'm implementing functionality to track which articles a user has read.

  create_table "article", :force => true do |t|     t.string   "title"     t.text     "content"   end 

This is my migration so far:

create_table :user_views do |t|   t.integer :user_id   t.integer :article_id end 

The user_views table will always be queried to look for both columns, never only one. My question is how my index should look like. Is there a difference in the order of these tables, should there be some more options to it or whatever. My target DB is Postgres.

add_index(:user_views, [:article_id, :user_id]) 

Thanks.

UPDATE:
Because only one row containing the same values in both columns can exist (since in knowing if user_id HAS read article_id), should I consider the :unique option? If I'm not mistaken that means I don't have to do any checking on my own and simply make an insert every time a user visits an article.

like image 937
Emil Ahlbäck Avatar asked May 29 '11 19:05

Emil Ahlbäck


People also ask

Is indexes allowed in multiple columns?

A composite index is an index on multiple columns. MySQL allows you to create a composite index that consists of up to 16 columns. A composite index is also known as a multiple-column index.

What will happen if you apply index on multiple-column?

An index with more than one column aggregates the contents.

Can we create index on multiple columns in SQL?

Multicolumn indexes can: be created on up to 32 columns. be used for partial indexing.

Can there be multiple index per table?

Yes you can have too many indexes as they do take extra time to insert and update and delete records, but no more than one is not dangerous, it is a requirement to have a system that performs well.


1 Answers

The order does matter in indexing.

  1. Put the most selective field first, i.e. the field that narrows down the number of rows fastest.
  2. 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 on user_id or user_id AND article_id, but NOT on article_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 } 
like image 158
sscirrus Avatar answered Sep 23 '22 13:09

sscirrus