ruby-on-rails - Join tables in ActiveRecord Migrations
问题描述
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?
解决方案
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:
推荐阅读
- python-3.x - Keras 3D 输入到 1D 输出
- r - ggplot facet_wrap() 中的多个正态分布
- firebase - 错误:await 表达式只能在异步函数中使用。尝试用“async”或“async*”标记函数体
- javascript - 为什么在发送 POST 请求时使用 JSON 上的 FormData?
- javascript - 重新加载选项卡的一部分和它的标签计数器,但没有刷新页面就呆在那里
- java - 从 MS Access 数据库中的表访问数据时出现 java.lang.NullPointerException
- reactjs - 使用 Firebase 设置带有功能组件的 React App
- flutter - Flutter - GridView 自定义大小问题
- javascript - 按钮制作盒子并在里面添加计数的数字
- swagger - 如何在 swagger 中指定没有指定键的通用映射