20

次の例をご覧ください。

  • これが適切な場合
  • これが適切でない場合

データベースの選択が上記の例に違いをもたらす時期はありますか?

4

7 に答える 7

40

これは実際には、常に自動インクリメント番号またはGUIDのいずれかであるため、単一の列であるサロゲートキーと、真に一意であるために複数の情報を必要とすることが多い自然キーに関する質問のようです。1列しかない自然キーを持つことができれば、とにかく要点は明らかに議論の余地があります。

どちらか一方だけを使用することを主張する人もいます。本番データベースでの作業に十分な時間を費やすと、コンテキストに依存しないベストプラクティスがないことがわかります。

これらの回答の一部はSQLServerの用語を使用していますが、この概念は通常、すべてのDBMS製品に適用できます。


単一列の代理キーを使用する理由:

  • クラスター化インデックス。 クラスター化インデックスは、データベースが単に追加できる場合に常に最高のパフォーマンスを発揮します。それ以外の場合、DBはページ分割を行う必要があります。これは、キーがシーケンシャルである場合、つまり自動インクリメントシーケンスまたはシーケンシャルGUIDの場合にのみ適用されることに注意してください。任意のGUIDは、パフォーマンスが大幅に低下する可能性があります。

  • 関係。キーが3、4、5列の長さで、文字タイプやその他の非コンパクトデータを含む場合、他の20のテーブルでこのキーとの外部キー関係を作成する必要があると、膨大なスペースが無駄になり、パフォーマンスが低下します。

  • 独自性。真の自然キーない場合があります。たぶん、あなたのテーブルはある種のログであり、同じイベントを同時に2つ取得する可能性があります。または、実際のキーは、行がすでに挿入されたでのみ決定できるマテリアライズドパスのようなものである可能性があります。いずれにせよ、クラスター化インデックスや主キーを常に一意にする必要があるため、他に本当に一意の情報がない場合は、代理キーを使用するしかありません。

  • 互換性。 ほとんどの人はこれに対処する必要はありませんが、自然キーにhierarchyidのようなものが含まれている場合、一部のシステムはそれを読み取ることさえできない可能性があります。この場合も、これらのアプリケーションで使用するための単純な自動生成された代理キーを作成する必要があります。自然キーに「奇妙な」データがない場合でも、この問題はすぐに解消されますが、一部のDBライブラリでは複数列の主キーの処理に多くの問題が発生します。

複数列の自然キーを使用する理由

  • ストレージ。データベースを扱う多くの人々は、この要因を気にする必要があるほど大きなデータベースを扱うことは決してありません。ただし、テーブルに数十億または数兆の行がある場合は、このテーブルに可能な限り最小限のデータを保持する必要があります。

  • レプリケーション。はい、GUIDまたはシーケンシャルGUIDを使用できます。ただし、GUIDには独自のトレードオフがあり、何らかの理由でGUIDを使用できない、または使用したくない場合は、本質的にグローバルに一意であるため、複数列の自然キーがレプリケーションシナリオに適しています。つまり、一意にするために特別なアルゴリズムは必要ありません。定義上、一意です。これにより、分散アーキテクチャについての推論が非常に簡単になります。

  • パフォーマンスの挿入/更新。代理キーは無料ではありません。一意頻繁にクエリが実行される列のセットがあるため、これらの列にカバーインデックスを作成する必要がある場合。インデックスはテーブルとほぼ同じ大きさになり、スペースを浪費、変更を加えるたびに2番目のインデックスを更新する必要があります。テーブルにインデックス(クラスター化インデックス)を1つだけ持つことが可能な場合は、それを行う必要があります。


それがすぐに頭に浮かぶことです。急に何か覚えたら更新します。

于 2010-02-05T01:41:35.310 に答える
5

ほとんどの場合、主キーが必要なので、既存の2つの列を主キーとして選択するか、新しい自動インクリメントPKを作成して、代わりに2つの列に通常の一意性制約を設定するかを選択すると思います。

2列の主キーが必要な場合:

  • 他の2つのテーブルを参照する中間テーブルがあり、それが2つの外部キーのみで構成されている場合、つまり多対多の関係がある場合、主キーとしてのみ列を追加しても意味がありません。すでに持っている2つの列を主キーとして使用します。

自動インクリメントの主キーが必要な場合:

  • 別のテーブルからテーブルを参照している場合は、ターゲットテーブルの主キーを小さくする必要があります。これは、そのデータが参照テーブルの外部キーとして繰り返されるためです。また、比較が高速であることも必要です。
  • テーブルに追加するすべてのインデックスには、クラスタリングキー(通常は主キーと同じ)のコピーが含まれます。クラスタリングキーが必要以上に大きい場合、そのテーブルのすべてのインデックスも必要以上に大きくなります。
于 2010-02-05T01:09:31.693 に答える
5

ほとんどの場合、(少なくともアプリケーション開発者の観点からは)主キーを自動生成キーにし、複数の列にUNIQUE制約とインデックスを作成する方が良いと思います。

  • 自動生成された単一の主キーを使用すると、他のテーブルからこのテーブルへの参照を簡単に追加できます。
  • 自動生成された主キーは、ORMライブラリでより簡単に機能します。
  • また、一意性の制約が将来変更された場合でも、既存の主キーを変更する必要はありません。

DBAは複数列の主キーで常に十分であると考えていたため、頭痛を引き起こすいくつかの状況に遭遇しました。将来の要件の変更により、これが正しくないことが判明しました。

于 2010-02-05T01:11:41.097 に答える
1

いくつかの例...

適切な:

  • OLTPシステム、ほとんどの状況で、ほとんどの多対多の関係を実装します。

不適切:

  • OLAPシステムのディメンションテーブルの場合-ファクトテーブルをできるだけ小さく(そして高速に)するために、ディメンションキーをできるだけ小さくする必要があります。

  • 組み合わせがユニークかどうかわからないときのために。確かにこれはかなり厄介な例ですが、「Person」テーブルは複数列のPKには適していません。

于 2010-02-05T01:03:51.137 に答える
0

複数列のインデックスとキーを使用すると、アプリケーションのパフォーマンスが大幅に向上することがわかりました。これにより、最も一般的なクエリでインデックスを作成でき、select句全体がインデックスに含まれる可能性があるため、メインテーブルにもアクセスできませんでした。ただし、アプリとデータセットによって異なります。

于 2010-02-05T01:12:46.120 に答える
0

適切な場合の1つの例は、異なるテーブルを接続する外部キーフィールドを持つリンクテーブルがある場合です。

一般に、可能であれば、既存の識別フィールドを主キーとして使用することをお勧めします。自然なIDフィールドがなく、一意のPKを取得するために多くのフィールドを組み合わせる必要がある場合は、自動番号を使用することをお勧めします。2つ以上のフィールドを持つ主キーは乱雑になる可能性があります。

于 2010-02-05T01:05:11.660 に答える
-1

複合自然キーが直感的に理解できる場合があります。たとえば、会社のテーブル(PKはComapnyId)があり、その会社の詳細が列に表示されているとします。また、会社の歴史を通して会社のCEO名を保存する必要があります。自然な不変は、1つの会社が一度に1人のCEOしか持つことができないということです。次に、CompanyId(CompanyテーブルのCompanyIdへのFK)+FromDateの複合PKを使用してCompanyCeoテーブルを作成するのは直感的です。そのテーブルの他の列は、ToDateとCeoNameである可能性があります。このようにして、特定の日に1人のCEOだけが開始できることを保証できます。

于 2010-02-05T03:12:16.787 に答える