RoR中的多列索引
我正在实现function来跟踪用户已阅读的文章。
create_table "article", :force => true do |t| t.string "title" t.text "content" end
这是我迄今为止的迁移:
create_table :user_views do |t| t.integer :user_id t.integer :article_id end
总是会查询user_views表来查找两列,而不是只查找一列。 我的问题是我的索引应该如何。 这些表格的顺序是否有所不同,是否应该有更多的select。 我的目标数据库是Postgres。
add_index(:user_views, [:article_id, :user_id])
谢谢。
更新:
因为在两列中只有一行包含相同的值(因为知道user_id是否读过article_id),我应该考虑:unique选项吗? 如果我没有弄错,那就意味着我不必自己做任何检查,只要每次用户访问一篇文章时都插入。
订单在索引中很重要。
- 把最有select性的领域,即缩小行数最快的领域。
- 索引只会在从头开始按顺序使用列时使用。 即如果您在
[:user_id, :article_id]
上索引,则可以在user_id
或user_id AND article_id
上执行快速查询,但user_id AND article_id
上执行快速查询。
您的迁移add_index
行应该看起来像这样:
add_index :user_views, [:user_id, :article_id]
关于“独特”选项的问题
在Rails中执行此操作的简单方法是在您的模型中使用具有作用域uniqueness
validates
,如下所示( 文档 ):
validates :user, uniqueness: { scope: :article }
只是在validation时间和索引时检查唯一性的警告:后者是通过数据库完成的,而底层是由模型完成的。 由于可能同时运行一个模型的几个并发实例,所以validation会受到竞争条件的影响,这意味着在某些情况下可能无法检测到重复(例如,在同一时间提交两次相同的表单)。