3

「リンク テーブル」を作成することがよくあります。たとえば、次の表は、ユーザー レコードをイベント レコードにマップします。

CREATE TABLE [dbo].[EventLog](
    [EventId] [int] NOT NULL,
    [UserId] [int] NOT NULL,
    [Time] [datetime] NOT NULL,
    [Timestamp] [timestamp] NOT NULL
)

この質問では、EventId と UserId の組み合わせが一意であり、問​​題のデータベースが MS SQL Server 2008 インストールであると仮定してください。

私が抱えている問題は、これらのテーブルにどのようにインデックスを付ける必要があるかについて確信が持てないことです。たとえば、特定のイベントのすべてのユーザーを一覧表示したり、特定のユーザーのすべてのイベントを一覧表示したり、特定の EventId/UserId レコードを取得したりできます。私が検討したインデックス作成オプションは次のとおりです。

  1. EventId と UserId で複合主キーを作成します (ただし、UserId だけでアクセスする場合、インデックスが役に立たないことは理解しています)。
  2. EventId と UserId に複合主キーを作成し、UserId に補助インデックスを追加します。
  3. EventId に主キーを作成し、UserId に補助インデックスを作成します。

アドバイスをいただければ幸いです。

4

2 に答える 2

1

インデックスは、パフォーマンスの問題を解決するように設計されています。そのような問題がまだなく、どこで問題が発生するかを正確に把握できない場合は、インデックスを作成しないでください。インデックスはかなり高価です。ディスク容量を占有するだけでなく、データの書き込みまたは変更のオーバーヘッドが発生するためです。したがって、インデックスを作成することによって決定する特定のパフォーマンスの問題を明確に理解する必要があります。したがって、それを作成する必要性を理解できます。

于 2013-10-23T12:12:42.890 に答える
1

あなたの質問への答えは、いくつかの側面に依存します。

  1. 使用する DBMS によって異なります。単一列インデックス (Postgresql など) を好む人もいれば、複数列インデックス (Oracle など) をより活用できる人もいます。(sqlite のように) カバリング インデックスから完全にクエリに応答できるものもあれば、実際のテーブルのページを読み取ることができず、最終的にはそれを読み取らなければならないものもあります (これも postgres のように)。

  2. 回答したいクエリによって異なります。たとえば、両方向にナビゲートしますか、つまり、両方の Id 列で結合しますか?

  3. データ変更のスペースと処理時間の要件にも依存します。多くの場合、インデックスは実際にインデックスを作成するテーブルよりも大きく、インデックスを更新すると、基になるテーブルを更新するよりもコストがかかることに注意してください。

編集:

概念モデルが 2 つのエンティティ E1 と E2 の間に多対多の関係 R を持っている場合、つまり、R の論理セマンティクスが「関連」または「非関連」のいずれかである場合、R の結合された主キーを常に宣言するよりも. これにより、一意のインデックスが作成されます。ただし、主な動機はデータの一貫性であり、クエリの最適化ではありません。つまり、次のようになります。

CREATE TABLE [dbo].[EventLog](
    [EventId] [int] NOT NULL,
    [UserId] [int] NOT NULL,
    [Time] [datetime] NOT NULL,
    [Timestamp] [timestamp] NOT NULL,
    PRIMARY KEY([EventId],[UserId])

)

于 2013-10-23T12:13:02.687 に答える