15

私は、これを重複した質問にするように思われるもののいくつかを読みました。しかし、これらすべてを読んで、私は不安になりました。多くの質問/回答が議論に発展するため、以下の絶対的な例に基づいて回答を得たいと考えています。

私が持っている場合:

dbo.Book
--------
BookID PK int identity(1,1)

dbo.Author
----------
AuthorID PK int identity(1,1)

ここで、単純なジャンクション テーブルには 2 つの選択肢があります。

dbo.BookAuthor
--------------
BookID CPK and FK
AuthorID CPK and FK

上記は、両方の FK の複合/複合キーであり、両方の列の FK 関係を設定します - 削除時にカスケードも使用します。

また

dbo.BookAuthor
--------------
RecordID PK int identity(1,1)
BookID FK
AuthorID FK

BookID と AuthorID の外部キー関係、および削除時のカスケード。また、BookID と AuthorID に一意の制約を設定します。

上記の特定の例で、ある方法が別の方法よりも優れている理由についての簡単な答えを探しています。私が読んでいる回答は非常に詳細であり、複合キーに落ち着こうとしていたのですが、最初の例のように Identity 列を使用した例のビデオを見ました。

このトピックは少し半分に引き裂かれているように見えますが、私の直感は、複合キーを使用する必要があることを示しています。

クエリを効率的に行うにはどうすればよいですか? 2つの列に一意の制約を設定するとともに、PK ID列を持つようです.AND FK関係は、たとえ少しでもコストがかかります.

4

6 に答える 6

8

サロゲート キーの利点の確固たる支持者であり、その利点の普及者として、私はそれでもなお、最初の例のような全キー結合テーブルを例外としています。代理キーの利点の 1 つは、エンジンが通常、デフォルトで最も一般的な状況として、単一の整数フィールドで結合するように最適化されていることです。

最初の提案でもこの利点が得られますが、各インデックス レベルのファンプットが 50% 大きくなり、結合テーブルのインデックスの全体的なサイズと高さの両方が減少します。これによるパフォーマンス上の利点は、大規模なテーブルよりも小さい場合は無視できる可能性がありますが、ベスト プラクティスであり、コストはかかりません。

他の設計を選択する可能性があるのは、リレーションが追加の列を獲得する場合です。その時点で、厳密には結合テーブルではなくなります。

于 2015-03-04T00:45:18.117 に答える
7

私は、複合キーを使用する最初の設計を好みます。ジャンクション テーブルに ID 列があっても、親テーブルに ID 列があっても利点はありません。BookAuthorID 列を使用してクエリを実行するのではなく、 and を使用してクエリを実行しBookIDますAuthorID

また、ID を追加すると、制約を設けない限り、重複BookID-組み合わせが可能になります。AuthorID

さらに、主キーが(BookID, AuthorID)の場合、 にインデックスを作成する必要がありますAuthorID, BookID)。これは、著者が書いた本を照会したい場合に役立ちます。

于 2015-03-04T00:17:27.187 に答える
5

複合キーを使用することも私の選択です。理由は次のとおりです。

ストレージのオーバーヘッドが少ない

代理キーを使用するとします。特定の本についてすべての著者にクエリを実行したい場合や、その逆の場合は、BookId と AuthorId の両方で始まるインデックスが必要になるでしょう。パフォーマンス上の理由から、クラスタ化されたキー ルックアップを防ぐために、両方のインデックスに他の列を含める必要があります。重複する BookId/AuthorId の組み合わせがテーブルに追加されないように、そのうちの 1 つを一意にすることをお勧めします。

したがって、最終的な結果として:

  • データは 2 回ではなく 3 回保存されます
  • 1 つではなく 2 つの一意の制約が検証されます

ジャンクション テーブル参照テーブルのクエリ

Contributions (AuthorId, BookId, ...)ジャンクション テーブルを参照するようなテーブルを追加しても。ほとんどのクエリでは、ジャンクション テーブルを操作する必要はまったくありません。例: 特定の著者のすべての貢献を見つけるには、著者と貢献のテーブルのみが関係します。

于 2015-03-04T12:53:29.757 に答える
1

おそらく、複合/複合キーを使用する必要があります。このようにして、完全にリレーショナルになります。1 人の著者が多くの本を書くことができ、1 つの本が複数の著者を持つことができます。

于 2015-03-04T00:47:16.973 に答える