この質問は、この質問のコメントを読んだ後に出てきます。
多対多のテーブルを作成する場合、2つの外部キー列に複合プライマリキーを作成するか、自動インクリメントサロゲート「ID」プライマリキーを作成し、2つのFK列にインデックスを配置する必要があります。一意の制約)?それぞれの場合に新しいレコードの挿入/再インデックス付けのパフォーマンスにどのような影響がありますか?
基本的に、これ:
PartDevice
----------
PartID (PK/FK)
DeviceID (PK/FK)
対これ:
PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
コメント者のコメント:
2つのIDをPKにすると、ディスク上でテーブルがその順序で物理的にソートされます。したがって、(Part1/Device1)、(Part1/Device2)、(Part2/Device3)、(Part 1/Device3)を挿入すると、データベースはテーブルを分割し、最後のエントリをエントリ2と3の間に挿入する必要があります。多くのレコードでは、レコードが追加されるたびに数百、数千、または数百万のレコードがシャッフルされるため、これは非常に問題になります。対照的に、自動インクリメントPKを使用すると、新しいレコードを最後まで追加できます。
私が求めている理由は、代理自動インクリメント列を使用せずに複合主キーを実行する傾向が常にあったためですが、代理キーが実際にパフォーマンスが高いかどうかはわかりません。
単純な2列の多対多マッピングでは、代理キーを持つことには実質的な利点はありません。 (col1,col2)
に主キーを持つことは一意であることが保証され(参照テーブルのcol1
およびcol2
値が一意であると仮定)、(col2,col1)
に個別のインデックスがある場合、反対の順序で実行が速くなります。代理はスペースの無駄です。
テーブルは参照される2つのテーブルを結合するためにのみ使用されるため、個々の列にインデックスは必要ありません。
私が思うに、あなたが質問で言及するコメントは、それが使用する電子の価値はありません。著者は、テーブルは非常に高性能なバランスのとれた多方向ツリー構造ではなく、配列に格納されていると考えているようです。
はじめに、tableソートされたインデックスだけを保存または取得する必要はありません。また、インデックスはstoredではなく、迅速に取得できるように効率的な方法で格納されます。
さらに、データベーステーブルの大部分は、読み取られるfarよりも頻繁に読み取られます。これにより、選択側で行うことは、挿入側で行うことよりもはるかに関連性が高くなります。
リンクテーブルには代理キーは必要ありません。
(col1、col2)の1つのPKと(col2、col1)の別の一意のインデックスで十分です。
対処できないDBデザインを指示するORMを使用しない限り...
編集:私はここで同じ答えをしました: SQL:多対多テーブルに自動増分主キーが必要ですか?
テーブルが参照される場合、増分主キーが必要になる場合があります。多対多のテーブルには、増分主キーを使用して別のテーブルからプルアップする必要がある詳細があります。
例えば
PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
Other Details
FKとしてPartDevice.IDを使用して「その他の詳細」を取得するのは簡単です。したがって、増分主キーの使用が必要です。
私があなたの質問に答えることができる最も短くて最も直接的な方法は、リンクしている2つのテーブルが順次主キーを持っていない場合、パフォーマンスに影響があると言うことです。あなたが述べた/引用したように、リンクテーブルのインデックスは断片化されるか、リンクテーブルがそれ自体のシーケンシャルプライマリキーを持っていない場合、DBMSはレコードを挿入するためにより懸命に働きます。これが、ほとんどの人がリンクテーブルに連続的に増加する主キーを配置する理由です。
したがって、2つのテーブルをリンクするだけの場合、最適なPKはデュアルカラムPKになります。
しかし、他の目的に役立つ場合は、外部キーと2番目の一意のインデックスを持つPKとして別のNDXを追加します。
インデックスまたはPKは、重複がないことを確認するための最良の方法です。 PKを使用すると、Microsoft Management Studioなどのツールで作業の一部(ビューの作成)を実行できます