サロゲート/人工キーの一般的な利点の1つは理解しています。変更されないため、非常に便利です。これは、それらが「人工的」である限り、それらが単一フィールドであっても複数フィールドであっても当てはまります。
ただし、各テーブルの主キーとして自動インクリメント整数フィールドを持つことは、ポリシーの問題であるように見える場合があります。これは常に、このようなsingle-fieldキーを使用するのに最適なアイデアであり、その理由(または理由)は何ですか?
明確にするために、この質問は人工的なものと自然なものではなく、すべての人工的なキーをsingle-fieldにするかどうかについてです
番号。
単一フィールドのキーが複合キーよりも劣る場合は確かにあると思います少なくとも外部キーの目的では。必要に応じて、単一フィールドの代理キーも必要ないというわけではありませんが、個人的には、主キーと呼ばれる外部キーのターゲットとして最も頻繁に使用されるキーを好みます
次の例で私のポイントを説明しようとします。
brand
はカーマーキーです。例:フォード、トヨタなどdealer
は、ブランドに関連付けられた実際のディーラーです(例:Fordのみを販売するFordディーラー)。model
は車のタイプです。例:フォードフォーカス、フォードフィエスタなどstock
は、各ディーラーの現在の前庭の車両数です次のようにdealer
とmodel
の単一フィールド代理キーを作成すると、
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) )
その後、Ford stock
を「Toyota」モデルにリンクするdealer
に行を挿入できます。 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 )
「フォード」ディーラーが「フォード」車のみをストックできるというルールは、モデルによって自然に適用されます。
「複合キー」の例では、好みに応じてdealer_id
が一意である場合とそうでない場合があることに注意してください。一意である必要はありません(つまり、代替キー)。ただし、一意にすることで失われることはほとんどなく(おそらく少しのストレージスペース)、非常に便利なため、通常は次のように設定します。
create table dealer( brand_id integer references brand,
dealer_id serial unique,
primary key(brand_id, dealer_id) )
いいえ、常にというわけではありませんが、ほとんどの場合はそうです。
これらは、代理キーまたは人工キーが不要な状況です。
古い忠実な単調増加整数代理キーが理想的でない状況もいくつかあります。英数字のサロゲートであるキーを持つことができます。これらには以下が含まれます。
なぜほとんどの場合はい?その質問に対する最も基本的な答えは、テーブルの主キー値を変更する必要がある場合、それは純粋な地獄であるということです。 almostユーザーが見ることができるものはすべて、ある時点で更新される可能性があるため、目に見えるキー値を使用すると、純粋に地獄を引き起こします。サロゲートキーを使用すると、このトラップに陥ることはありません。
そうは言っても、YAGNIにはこの概念を適用する余地があることを忘れないでください。 IDENTITYキーを含むコードテーブルをスキーマの隅々まで押し込む必要はありません。従業員テーブルの男性の性別の記号をMからXに変更する必要があると誰かが判断した場合に備えて、なんかばかげています。
"場合によります"
はい:自然キーの幅が広く、数値でない場合は、サロゲートIDENTITY/AUTONUMBERフィールドが適しています。注:これは、SQL ServerやSybaseなどでデフォルトで発生する「PK」とクラスター化インデックスの融合を前提としています。
いいえ:2つの親キーで十分な場合は、テーブルの数が多くなります。または、自然キーが短く固定長である場合(通貨コードなど)
もちろん、脳死したORM(read:(n)Hibernate)はこれらのルールに勝ることがあります...
編集:もう一度質問を読む
2つの代理親キーを持つ多/多テーブルには、複数列のPKがあります。
ただし、別のサロゲート列は必要ありません。
テーブルにサロゲート(IDENTITYなど)キーがある場合、複数の列である必要はありません。
サロゲートを含むスーパーキーを持つことができますが、これは他のルールを適用することになります(例 サブタイプ )