何时在Rails中添加表中的索引
我有一个关于Rails数据库的问题。
- 我应该添加“索引”的所有外键像“xxx_id”?
- 我应该将“索引”添加到自动创build的“ID”列吗?
-
我应该添加“索引(唯一)”自动创build“ID”列?
-
如果我一次向两个外键添加索引(
add_index (:users, [:category, :state_id])
,会发生什么?这与为每个键添加索引有何不同?class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.string :name t.integer :category_id t.integer :state_id t.string :email t.boolean :activated t.timestamps end # Do I need this? Is it meaningless to add the index to the primary key? # If so, do I need :unique => true ? add_index :users, :id # I don't think I need ":unique => true here", right? add_index :users, :category_id # Should I need this? add_index :users, :state_id # Should I need this? # Are the above the same as the following? add_index (:users, [:category, :state_id]) end end
很好的答案。 附加问题。
- 我应该添加“唯一索引”为xxx_id,对不对?
我应该添加“索引”的所有外键像“xxx_id”?
这样会更好,因为它加快了在这一列的sortingsearch。 而外键是search了很多东西。
我应该将“索引”添加到自动创build的“ID”列吗?
不,这已经通过铁轨完成了
我应该添加“索引(唯一)”自动创build“ID”列?
不,和上面一样
如果我一次向两个外键添加索引(
add_index (:users, [:category_id, :state_id])
,会发生什么?这与为每个键添加索引有何不同?
那么这个索引是两列的组合索引。 这没有任何意义,除非你想要一个category_id
和一个state_id
(它应该是category_id
不是category
)的所有条目在同一时间。
像这样的索引会加速以下请求:
# rails 2 User.find(:all, :conditions => { :state_id => some_id, :category_id => some_other_id }) # rails 3 User.where(:state_id => some_id, :category_id => some_other_id)
哪里
add_index :users, :category_id add_index :users, :state_id
会加快这些要求:
# rails 2+3 User.find_by_category_id(some_id) User.find_by_state_id(some_other_id) # or # rails 2 User.find(:all, :conditions => {:category_id => some_id}) User.find(:all, :conditions => {:state_id => some_other_id}) # rails 3 User.where(:category_id => some_id) User.where(:state_id => some_other_id)
我应该添加“唯一索引”为xxx_id,对不对?
不,因为如果你这样做,只有一个用户可以在一个类别,但类别的含义是,你可以把更多的用户放在一个类别。 在你的User
模型中,你有这样的belongs_to :category
,在你的类别模型,像has_many :users
。 如果你有一个has_many
关系, foreign_key
字段不能是唯一的!
有关这方面的更详细的信息,你应该看看tadman的伟大的答案 。
索引可能是一个棘手的,微妙的事情,但有一些适用的一般规则,可以决定哪个更容易使用。
首先要记住的是索引可以以多种方式工作。 A,B,C上的索引也适用于A,B和A,因此如果您正确地对它们进行sorting,则可以将索引devise得更加通用。 电话簿是以姓氏,名字索引的,因此您可以通过姓氏或姓氏和名字的组合方便地查找人员。 但是,你不能直接按照他们的名字来查看它们。 你需要一个单独的索引。 电话号码也是一样,你也必须索引。
考虑到这一点,有很多事情会决定你如何创build索引:
- 如果你有一个
belongs_to
–has_many
关系配对,你需要在所用的外键上有一个索引。 - 如果您订购了您的logging,并且有大量的logging将被分页,那么您应该将该订单栏添加到索引的末尾。
- 如果您有
has_many :through
关系,那么您的连接表应该对作为复合键的连接所涉及的两个属性都有一个唯一的索引。 - 如果您使用唯一标识符(例如用户名或电子邮件)直接获取logging,则该logging应该是唯一的索引。
- 如果您使用作用域从
has_many
关系中获取logging集,请确保存在包含has_many
外键和作用域列的索引。
索引的目标是消除数据未正确索引时发生的可怕的“表扫描”或“文件sorting”操作。
简单来说,查看应用程序生成的查询,并确保在WHERE
或HAVING
条件中引用的列和ORDER BY
子句按该顺序表示。
- 始终索引外键
- 总是索引你将要命令的列
- 所有唯一字段(确保数据库级别的唯一性)迁移示例:
add_index :users, :email, unique: true
) - 如果您按两件事物sorting,或者按两件事search,例如:
order by [a, b]
或find where( a and b )
,则需要双重索引:
具体例子:
如果你有:
default_scope :order => 'photos.created_at DESC, photos.version DESC'
你应该添加:
add_index :photos, [:created_at, :version]
注意:索引会占用磁盘上的额外空间,并使其创build和更新每条logging的速度变慢,因为它必须重build每个索引。
信用:
https://tomafro.net/2009/08/using-indexes-in-rails-choosing-additional-indexes,rails – created_at当用户进行sorting时,是否需要在表中添加索引? ,以及上面的答案。