Ruby on Rails中多列的索引

Emi*_*äck 91 indexing database-design ruby-on-rails ruby-on-rails-3

我正在实现跟踪用户阅读的文章的功能.

  create_table "article", :force => true do |t|
    t.string   "title"
    t.text     "content"
  end
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止的迁移:

create_table :user_views do |t|
  t.integer :user_id
  t.integer :article_id
end
Run Code Online (Sandbox Code Playgroud)

始终会查询user_views表以查找两列,而不仅仅查找一列.我的问题是我的索引应该是什么样子.这些表的顺序是否存在差异,是否应该有更多选项或其他.我的目标数据库是Postgres.

add_index(:user_views, [:article_id, :user_id])
Run Code Online (Sandbox Code Playgroud)

谢谢.

更新:
因为只有一行在两列中都包含相同的值(因为在知道user_id是否读过article_id时),我应该考虑:unique选项吗?如果我没有弄错,那意味着我不必自己进行任何检查,只需在用户访问文章时插入即可.

ssc*_*rus 198

订单在索引中很重要.

  1. 首先放置最具选择性的字段,即最快缩小行数的字段.
  2. 仅当您从头开始按顺序使用其列时,才会使用该索引.即如果你索引[:user_id, :article_id],你可以在user_iduser_id AND article_id,但不是快速查询article_id.

您的迁移add_index行应如下所示:

add_index :user_views, [:user_id, :article_id]
Run Code Online (Sandbox Code Playgroud)

关于"独特"选项的问题

在Rails中执行此操作的简单方法是validates在模型中使用作用域uniqueness如下(文档):

validates :user, uniqueness: { scope: :article }
Run Code Online (Sandbox Code Playgroud)

  • 订单在索引方面非常重要.将where子句放在左侧,并使用右侧的排序列完成索引.http://stackoverflow.com/questions/6098616/dos-and-donts-for-indexes (6认同)
  • 请注意,“validates_uniqueness_of”(及其表亲“validates uniqueness:”)容易出现竞争条件 (2认同)

小智 21

只是关于检查验证时与索引的唯一性的警告:后者由数据库完成,而引物由模型完成.由于可能同时运行模型的多个并发实例,因此验证受竞争条件的影响,这意味着在某些情况下它可能无法检测到重复(例如,在同一时间提交两次相同的表单).

  • 都.validates_uniqueness_of可用于在应用程序中正常显示错误消息,例如表单保存时.数据库约束将确保您不会得到重复记录,即使您知道模型中指定了验证.另外,您可以拯救ActiveRecord异常并向用户显示一条好消息. (7认同)
  • @WM如果你必须选择一个,请使用数据库约束.即使不同的非RoR应用程序与您的数据交互,并且确保长期一致性,这也将起作用. (4认同)