我有一个表格,其中包含我通过以下迁移生成的多态参考:
def change
add_reference :table_name, :thing, polymorphic: true, index: true
end
当我运行迁移时,它会生成以下内容:
add_index "workflow_engine_task_bases", ["thing_type", "thing_id"], name: "index_workflow_engine_task_bases_on_thing_type_and_thing_id", using: :btree
为什么最左边的列是thing_type?对我来说,这似乎不是最理想的,因为它不那么具体。
答案 0 :(得分:5)
这是Rails by Derek Prior中的commit,在为多态关联生成索引时,add_reference
在type
之前更新id
。改变的理由如下:
在多列索引中首先使用类型列
add_reference
可以在您使用时非常有用地添加多列索引 它添加一个多态参考。但是,在第一列 index是id
列,不太理想。[PostgreSQL docs] [1]说:
多列B树索引可以与查询条件一起使用 涉及索引列的任何子集,但索引最多 在领先(最左边)有限制时有效 列。
[MySQL docs] [2]说:
MySQL可以对测试所有内容的查询使用多列索引 索引中的列,或仅测试第一列的查询, 前两列,前三列,依此类推。如果你指定 索引定义中的列顺序正确,单个 复合索引可以加快几种查询的速度 表
在多态关系中,类型列更有可能 作为索引中的第一列比id列有用。就是我,我 更有可能查询没有id的类型,而不是我在id上查询 没有类型。
[1]:http://www.postgresql.org/docs/9.3/static/indexes-multicolumn.html
[2]:http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html
我认为在大多数情况下,这个顺序是有道理的。它允许您拥有一个在包括type
和id
或仅type
的查询中表现良好的索引。
话虽如此,您的用例可能会有所不同,具体取决于您使用的数据库,数据集以及您计划运行的查询。最好的办法是在生产转储中分析最常见的用例,并相应地选择索引策略。
答案 1 :(得分:0)
来自http://apidock.com/rails/v4.2.7/ActiveRecord/ConnectionAdapters/SchemaStatements/add_reference。
在add_reference
的源代码中:
add_index(table_name, polymorphic ? [type id].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
它只是从type
位于id
之前的数组进行映射。不确定为什么会这样设计,但最好只使用add_index
。
add_index(:table, [:thing_id, :thing_type])