すべてのテーブルに単一フィールドのサロゲート/人工主キーが必要ですか?


33

代理キー/人工キーの一般的な利点の1つを理解しています。変更されないため、非常に便利です。これは、「人工」である限り、単一フィールドでも複数フィールドでも同じです。

ただし、各テーブルの主キーとして自動インクリメント整数フィールドを持つことはポリシーの問題のように思われる場合があります。これは常にそのような単一フィールドのキーを持っているのが最良のアイデアですか?なぜですか?

明確にするために、この質問は人工対自然に関するものではなく、すべての人工キーを単一フィールドにする必要があるかどうかに関するものです


回答:


28

私は言うつもりはない常に、いや、しかし時間イエスの最も。

これらは、代理キーまたは人工キーを必要としないいくつかの状況です。

  • 純粋な交差テーブル。インターセクションが外部キーのターゲットになるリスクがなく、インターセクションが独立した属性(つまり、2つの親テーブルに対するFK以外のもの)を引き付けるリスクがほとんどまたはまったくない場合は、組み合わせを使用して回避できます。 FKのPKとしての公正な自信。
  • 静的なビジネスキーを持つルックアップテーブル。あなたは、ルックアップしている場合
    、あなたに外部から固定されているユニークなビジネスキーを持つテーブルを
    持ってビジネスや常に変化のゼロチャンスいずれかのために
    、次に行うことができます直接ビジネスキーを使用して、実用的な目的
    のものは単純に。例としては、州または州の
    コードのリスト、またはANSI標準番号のリストなどがあります。
  • 複数の独立したソースから統合されたデータを含むテーブル。システムに多数のデータソースがあり、本社などで単一のテーブルに統合する必要がある場合、ソースシステムのキー値とソースシステムが何であるかを示すコードを含む複合キーが必要になる場合があります。

また、古い忠実な単調増加する整数代理キーが理想的ではない状況もあります。英数字のサロゲートであるキーを持つことができます。これらには以下が含まれます。

  • 複数の独立したソースからのデータをマージする必要がある状況。キーの衝突を避けるために、IDENTITYキーの代わりにGUIDを使用できます。
  • 数字以外のキー表現を使用せざるを得ない状況。ナンバープレートデータベースがあるとします。キーは、純粋な数値ではなく英数字の値にすることができます。
  • 外部要件があり、キー値に圧縮を適用する必要がある状況。int32に10桁を使用する代わりに、6桁の36桁を使用できます。

なぜほとんどの場合はイエスですか?その質問に対する最も基本的な答えは、テーブルの主キー値を変更する必要がある場合、それは純粋な地獄だということです。以来、ほとんど何もユーザーが見ることができるか、タッチが考えられるいくつかの点で、更新の対象に、純粋な地獄を招いている目に見えるキー値を使用しています。代理キーを使用すると、このトラップに陥ることがなくなります。

そうは言っても、YAGNIにはこの概念を適用する余地があることを忘れないでください。従業員テーブルの男性の性別の記号をMからXまたは愚かなものに変更する必要があると判断した場合に備えて、IDENTITYキーを持つコードテーブルをスキーマの隅々まで強制する必要はありません。


「サロゲートキーを使用すると、このトラップに陥るのを防ぐことができます」問題は、サロゲートと自然のサロゲートではなく、単一フィールドのサロゲートとマルチフィールドのサロゲートについてです。
ジャックダグラス

あなたがあなた自身の答えに対するコメントで認めたように、私たちはデータベース設計において賢明なことに関しては「同意しない」領域にいます。あなたの編集を考えると、代理キーと自然キーを区別しなかったので、2番目の箇条書きは遅ればせながらトピックから外れています。古典的なアイデンティティ/シーケンスアプローチからいつ逸脱する可能性があるかについての私の他のポイントは、依然として有効です。
ジョエルブラウン

あなたが歴史から見ることができるように私は、私はそれがスキムミルク、読者を助けるだろうと思っただけで追加重点を質問を変更しませんでした
ジャック・ダグラス

12

いや

少なくとも外部キーの目的上、単一フィールドキーが複合キーよりも劣る場合は確かにあると思います。それはあなたが望むなら単一フィールドの代理キーも持つべきではないということではありませんが、私は個人的には主キーと呼ばれる外部キーのターゲットとして最も頻繁に使用されるキーを好みます

次の例で私のポイントを説明しようとします。

  • brand フォード、トヨタなどの自動車ブランド
  • dealer ブランドに関連付けられた物理的なディーラーです(例:フォードのみを販売するフォードディーラー)
  • model フォードフォーカス、フォードフィエスタなどの車のタイプ
  • stock 各ディーラーの現在のフォアコートの車の数です

我々は、単一のフィールドサロゲートキーを作成した場合のためにdealermodel、以下のように:

create table brand( brand_id integer primary key );

create table dealer( dealer_id integer primary key, 
                     brand_id integer references brand )

create table model( model_id integer primary key, 
                    brand_id integer references brand )

create table stock( model_id integer references model, 
                    dealer_id integer references dealer, 
                    quantity integer,
                      primary key(model_id, dealer_id) )

次にstock、Ford dealerを「Toyota」モデルにリンクする行を挿入することができます。追加brand_id references brandしますstockだけで問題が悪化します。一方、外部キーを次のようにプライマリキーの一部として保持する場合:

create table brand( brand_id integer primary key );

create table dealer( brand_id integer references brand, 
                     dealer_id integer, 
                       primary key(brand_id, dealer_id) )

create table model( brand_id integer references brand, 
                    model_id integer, 
                      primary key(brand_id, model_id) )

create table stock( brand_id integer, 
                    model_id integer, 
                    dealer_id integer, 
                    quantity integer,
                      primary key(brand_id, model_id, dealer_id),
                      foreign key(brand_id, model_id) references model,
                      foreign key(brand_id, dealer_id) references dealer )

現在、「Ford」ディーラーは「Ford」車のみを在庫できるというルールがモデルによって自然に施行されています。

「複合キー」の例でdealer_idは、好みに応じて一意である場合と一意でない場合があることに注意してください。一意である必要はありません(つまり、代替キー)が、そうすることによって失われることはほとんどなく(おそらく少しのストレージスペース)、非常に便利になる可能性があるので、通常は次のように設定します。

create table dealer( brand_id integer references brand, 
                     dealer_id serial unique, 
                       primary key(brand_id, dealer_id) )

3
あらゆる角度から必ずしも完全であるとは限らない例についての通常の条件を考慮に入れて、このタイプの設計は特にもろいと言います。DRIを使用してビジネスルールを実施する方法を見つけることには満足のいくものがありますが、変更に対応する能力も失われます。トヨタがフォードを購入する場合、またはフォードディーラーが中古のトヨタを販売することを決定した場合でも、DRI主導のビジネスルールはメンテナンスの頭痛の種になります。
ジョエルブラウン

1
したがって、「ビジネスルールが変更される可能性があります」。これはどのビジネスルールにも当てはまり、常にモデルの変更が潜在的に困難になる可能性があります。私は通常、取得語ったビジネスルールが何であるか-私は自分自身のためにそれらを決定していません。
ジャックダグラス

1
ビジネスルールを実施するためにDRIをまったく使用すべきではないと言っていますか?DRIが行うのはそれだけではありませんか?-単純な外部キーであっても、DRIによって強制されるビジネスルールです。
ジャックダグラス

4
もちろん、DRIはビジネスルールを実施します。コードで適用されるルールとスキーマで適用されるルールを決定する必要があります。スキーマの変更は、ほとんどの場合、コードの変更よりも困難です。データモデルに適用できるビジネスルールには2種類あります。1つはそこに属し、もう1つは属しません。ビジネスにとって重要なデータの基本的な性質は、ほとんど変わりません。そのデータを操作する特定の方法は、はるかに不安定です。車にメーカーがあるというルールは、データモデルに属します。ディーラーのようなルールでは、2つのブランドの車を販売することはありません。
ジョエルブラウン

4
「スキーマの変更は、ほとんどの場合、コードの変更よりも困難です」IMOはその逆です。実際、私はあなたが言った事実すべてに同意しませんが、あなたとトスすることを主張する点があるとは思わないので、私はそれをそのままにします。
ジャックダグラス

12

"場合によります"

はい:サロゲートIDENTITY / AUTONUMBERフィールドは、自然キーが広く非数値の場合に適しています。注:これは、「PK」とSQL ServerおよびSybaseなどでデフォルトで発生するクラスター化インデックスの融合を前提としています。

いいえ:2つの親キーで十分な場合、多数/多数のテーブル。または、自然キーが短く固定長の場合(通貨コードなど)

もちろん、ブレインデッドORM(読む:(n)Hibernate)はこれらのルールに勝つかもしれません...

編集:質問をもう一度読む

2つの代理親キーを持つ多/多テーブルには、複数列PKがあります。
ただし、別のサロゲート列は必要ありません。

テーブルにサロゲート(IDENTITYなど)キーがある場合、複数の列である必要はありません。

サロゲートを含むスーパーキーを持つことができますが、これは他のルール(サブタイプなど)を実施するためです

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.