Reputation: 9407
I was reading the Rails Guides and discovered a new syntax for creating join tables:
class CreateJoinTableCustomerProduct < ActiveRecord::Migration[5.0]
def change
create_join_table :customers, :products do |t|
# t.index [:customer_id, :product_id]
# t.index [:product_id, :customer_id]
end
end
end
Perhaps this helper method create_join_table is new in Rails 5 and generates the appropriate join table in schema.rb. But it is this part that perturbed me:
# t.index [:customer_id, :product_id]
# t.index [:product_id, :customer_id]
Typically, if you want to add an index to a column, you do something like this:
add_index :products, :product_id
But why in this migration are there two indexes, with the same two columns? What is the explanation of this syntax?
Upvotes: 1
Views: 321
Reputation: 101811
Database indexes are not limited to a single column.
t.index [:customer_id, :product_id]
Passing an array creates a compound index which indexes the combination of two columns - which is exactly what a join table is.
This can for example be used to enforce the uniqueness of a combination of values:
t.index [:user_id, :coupon_id], unique: true
Or just speed up queries.
The reason Rails creates two seperate indexes:
# t.index [:customer_id, :product_id]
# t.index [:product_id, :customer_id]
Is that the order actually matters for performance - a grossly simplefied rule of thumb for b-tree indexes is that you should place the most selective column first. You are supposed to choose the best compound index for your use case.
See:
Upvotes: 2