Ruby on rails 如何正确索引Rails联接表迁移中的字段?

Ruby on rails 如何正确索引Rails联接表迁移中的字段?,ruby-on-rails,Ruby On Rails,Rails 4引入了用于生成联接表迁移的功能: bin/rails generate migration CreateTeamsUsersJoinTable team user 这将生成以下文件: class CreateTeamsUsersJoinTable < ActiveRecord::Migration def change create_join_table :teams, :users do |t| # t.index [:team_id, :user

Rails 4引入了用于生成联接表迁移的功能:

bin/rails generate migration CreateTeamsUsersJoinTable team user
这将生成以下文件:

class CreateTeamsUsersJoinTable < ActiveRecord::Migration
  def change
    create_join_table :teams, :users do |t|
      # t.index [:team_id, :user_id]
      # t.index [:user_id, :team_id]
    end
  end
end

您可以看到索引被注释掉了。为什么会这样?我应该决定使用哪一种吗?或者他们是在暗示指数是可选的?我想确保每个字段都有某种索引以避免性能问题,但我不确定如何正确定义这些字段的索引。

我不得不说,这背后的目的是让您选择更适合自己的策略。这通常是一个有两个标准的决定

索引会增加多少开销 如何查询数据库 因此,他们不能为您做出这样的决定,并将索引开销作为惯例添加进来

为了做出决定,您需要知道如何查询数据库。在MySQL中,复合索引可以用于一组查询。

列a、列b、列c上的索引将用于查询

这三个领域都在一起 a列 列a和列b在一起 所以两者之间有区别

t.index [:team_id, :user_id]

实际需要的完整索引集是

t.index [:team_id, :user_id]
t.index :user_id

为了处理索引所有三种情况

实例 如果您发现您的应用程序更频繁地使用以下查询:

user.teams转换为

从user_id=X的团队中选择*

关于用户id或用户id、团队id的索引非常方便


所以t.index[:user\u id,:team\u id]应该是您的选择

要完成xlembouras答案,您可以根据查询表的方式进行选择

例如,如果有一个视图显示给定团队的用户,则查询将如下所示:

SELECT user.name FROM team_users tu 
INNER JOIN users u 
ON tu.user_id = u.id
WHERE tu.team_id = X
这得益于t.index[:team\u id,:user\u id],而不是t.index[:user\u id,:team\u id]

数据库将只在第一个索引上使用一个索引查找来检索用户ID

如果您有一个显示给定用户团队的视图,则查询如下:

SELECT team.name FROM team_users tu 
INNER JOIN team t 
ON tu.team_id = t.id
WHERE u.user_id = X
这得益于t.index[:user\u id,:team\u id],而不是t.index[:team\u id,:user\u id]

数据库将只在第一个索引上使用一个索引seek来检索团队ID

这是因为组合索引的存储方式:


谢谢,这真的很有帮助,但我还是很难理解。你能详细说明一下这些例子之间的区别吗?例如,team.users和user.teams的组合更好吗?另外,假设我在开发中使用SQLite,在生产中使用PostgreSQL……基于支持的索引,应该使用哪些索引有区别吗?请阅读并顺便说一句,SQLite和PostgreSQL之间没有区别。阅读您的好答案后,我突然想到,在简单的联接表中,compund索引(也称为复合索引)和double索引是没有意义的。由于联接表用于在一个方向上查询数据,如您的示例中所示,因此我们应该使用简单的单列索引。我们永远不会查询特定的用户id和团队id,因为这只会给我们关联行,没有额外的数据。还是我弄错了。。。?
SELECT user.name FROM team_users tu 
INNER JOIN users u 
ON tu.user_id = u.id
WHERE tu.team_id = X
SELECT team.name FROM team_users tu 
INNER JOIN team t 
ON tu.team_id = t.id
WHERE u.user_id = X