Ruby on Railsの複数の列のインデックス


97

ユーザーが読んだ記事を追跡する機能を実装しています。

  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テーブルは、常に1つだけではなく、両方の列を検索するために照会されます。私の質問は私のインデックスがどのように見えるべきかです。これらのテーブルにいくつかのオプションがある場合、これらのテーブルの順序に違いはありますか?私のターゲットDBはPostgresです。

add_index(:user_views, [:article_id, :user_id])

ありがとう。

更新:
両方の列に同じ値を含む行は1つしか存在できないため(user_idがarticle_idを読み取ったかどうかを知るため)、: uniqueオプションを検討する必要がありますか?私が誤解していないのであれば、それは自分でチェックする必要がなく、ユーザーが記事にアクセスするたびに挿入するだけです。


「user_viewsテーブルは、常に1つだけではなく、両方の列を検索するために照会されます。」-「このユーザーが表示したすべての記事を検索する」、または「この記事を表示したすべてのユーザーを検索する」クエリはありませんか?それは驚くべきことです。
David Aldridge 2015

回答:


212

インデックス作成では、順序は重要です。

  1. 最も選択的なフィールドを最初に配置します。つまり、行数を最も速く絞り込むフィールドです。
  2. インデックスは、最初から順番に列を使用する場合にのみ使用されます。つまり、でインデックスを作成すると[:user_id, :article_id]user_idまたはuser_id AND article_idで高速クエリを実行できますが、で実行できませんarticle_id

移行add_index行は次のようになります。

add_index :user_views, [:user_id, :article_id]

「ユニーク」オプションに関する質問

Railsでこれを行う簡単な方法は、次のようにvalidatesスコープさuniquenessれたモデルで使用することです(ドキュメント):

validates :user, uniqueness: { scope: :article }

7
順序付けは、索引付けにおいて非常に重要です。where句を左側に配置し、列を右側に並べてインデックスを完成させます。stackoverflow.com/questions/6098616/dos-and-donts-for-indexes
Denis de Bernardy '29

1
validates_uniqueness_of(およびその従兄弟validates uniqueness:)は競合状態になりやすいことに注意してください
Ben Aubin

1
上記のコメント、stackoverflow.com / a / 1449466/5157706およびstackoverflow.com/a/22816105/5157706で述べたように、データベースに一意のインデックスを追加することも検討してください。
Akash Agarwal

25

検証時とインデックス時の一意性のチェックに関する警告です。後者はデータベースによって実行され、プライマーはモデルによって実行されます。同時に実行されるモデルの複数のインスタンスが存在する可能性があるため、検証は競合状態の影響を受けます。つまり、場合によっては重複の検出に失敗する可能性があります(たとえば、同じフォームを2回同時に送信するなど)。


どちらが良いですか?データベース側またはvalidates_uniqueness_of?
WM

9
両方とも。validates_uniqueness_ofを使用すると、たとえばフォームが保存されたときに、アプリケーションでエラーメッセージを適切に表示できます。データベースの制約により、モデルで検証が指定されていることを知っていても、重複レコードが発生しないようになります。さらに、ActiveRecord例外を救済し、ユーザーに素敵なメッセージを表示することもできます。
UģisOzols

5
@WMいずれかを選択する必要がある場合は、データベースの制約に従います。これは、異なるRoR以外のアプリケーションがデータと相互作用する場合でも機能し、長期にわたって一貫性を保証します。
2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.