ruby-on-rails - 如果我用另一列索引外键,是否需要显式索引它?
问题描述
我正在经历这个例子:
class CreateArtworkShares < ActiveRecord::Migration[5.2]
def change
create_table :artwork_shares do |t|
t.integer :artwork_id, null: false
t.integer :viewer_id, null: false
t.timestamps
end
add_index :artwork_shares, :artwork_id
add_index :artwork_shares, :viewer_id
add_index :artwork_shares, [:artwork_id, :viewer_id], unique: true
end
end
我指的是这个 Stack Overflow 帖子:Index on multiple columns in Ruby on Rails
我对为什么这个例子中的解决方案显式索引 :artwork_id 感到有点困惑。使用 :artwork_id 和 :viewer_id (代码中索引的最后一行)的索引是否已经为 :artwork_id 创建了索引?而且我还想知道是否有一种简单的方法来决定最后一个索引行中列的顺序。我通读了上面发布的 Stack Overflow 答案,但是关于这些列的顺序的解释对于我来说有点太笼统了,无法理解这个概念。
解决方案
使用 :artwork_id 和 :viewer_id (代码中索引的最后一行)的索引是否已经为 :artwork_id 创建了索引?
不。只有在查询两列时才使用复合索引——这就是重点。它是组合的索引。
irb(main):001:0> ArtworkShare.where(viewer_id: 1).explain
ArtworkShare Load (0.8ms) SELECT "artwork_shares".* FROM "artwork_shares" WHERE "artwork_shares"."viewer_id" = $1 [["viewer_id", 1]]
=> EXPLAIN for: SELECT "artwork_shares".* FROM "artwork_shares" WHERE "artwork_shares"."viewer_id" = $1 [["viewer_id", 1]]
QUERY PLAN
------------------------------------------------------------------------------------------------
Bitmap Heap Scan on artwork_shares (cost=4.20..13.67 rows=6 width=40)
Recheck Cond: (viewer_id = '1'::bigint)
-> Bitmap Index Scan on index_artwork_shares_on_viewer_id (cost=0.00..4.20 rows=6 width=0)
Index Cond: (viewer_id = '1'::bigint)
(4 rows)
irb(main):002:0> ArtworkShare.where(viewer_id: 1, artwork_id: 1).explain
ArtworkShare Load (1.7ms) SELECT "artwork_shares".* FROM "artwork_shares" WHERE "artwork_shares"."viewer_id" = $1 AND "artwork_shares"."artwork_id" = $2 [["viewer_id", 1], ["artwork_id", 1]]
=> EXPLAIN for: SELECT "artwork_shares".* FROM "artwork_shares" WHERE "artwork_shares"."viewer_id" = $1 AND "artwork_shares"."artwork_id" = $2 [["viewer_id", 1], ["artwork_id", 1]]
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Index Scan using index_artwork_shares_on_artwork_id_and_viewer_id on artwork_shares (cost=0.15..8.17 rows=1 width=40)
Index Cond: ((artwork_id = '1'::bigint) AND (viewer_id = '1'::bigint))
(2 rows)
而且这种迁移很好……很糟糕。
class CreateArtworkShares < ActiveRecord::Migration[6.0]
def change
create_table :artwork_shares do |t|
t.belongs_to :artwork, null: false, foreign_key: true
t.belongs_to :viewer, null: false, foreign_key: true
t.timestamps
end
add_index :artwork_shares, [:artwork_id, :viewer_id], unique: true
end
end
artwork_id
这会在和上添加外键约束和索引viewer_id
。它还创建bigint
而不是常规整数列。
我还想知道是否有一种简单的方法来决定最后一个索引行中列的顺序。
不,没有简单的方法。这取决于应用程序中的访问路径。
推荐阅读
- jquery - 我不知道这是什么意思 SyntaxError: expected expression, got keyword 'else'
- ms-word - 我们可以直接在清单中配置支持的平台吗
- r - R纯文本中的仇恨语音检测
- android - 用于跨平台消息的 Firebase 云消息传递格式
- java - 如何在我的 showMessageDialog 中显示两个文本字段 actionListener?哈尔普
- python - 列出目录 jupyter 中的 csv 文件
- amazon-web-services - Terraform Autoscaling - 默认开启详细监控
- python - 在失败的 Avro 验证中提供有用的错误
- windows-10 - Autohotkey:重新映射 Win 键 - 单独按下时
- reactjs - 警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。反应两个按钮功能冲突