外部キー-代理キーまたは自然キーを使用してリンクしますか?


14

テーブル間の外部キーを自然キーまたはサロゲートキーにリンクするかどうかのベストプラクティスはありますか?私が本当に見つけた唯一の議論は(私のgoogle-fuが欠けていない限り)この質問でのJack Douglasの答えです。私はルールが変わるということを超えた議論を知っていますが、これはどんな状況でも考慮する必要があるものです。

尋ねる主な理由は、自然キーを持つFKを使用するレガシーアプリケーションがあることですが、開発者からOR / M(この場合はNHibernate)に移行する強いプッシュがあり、フォークは既にいくつかを生成していることです変更を壊すので、自然キーを使用して変更を元に戻すか、FKのサロゲートキーを使用するようにレガシーアプリを移動します。私の腸は元のFKを復元すると言っていますが、これが本当に正しい道かどうかは正直わかりません。

テーブルの大部分には、既に一意キーとPKが定義された代理キーと自然キーの両方が既に定義されているため、このインスタンスでは余分な列を追加する必要はありません。SQL Server 2008を使用していますが、これがすべてのDBに十分な汎用性を持っていることを願っています。

回答:


15

SQLもリレーショナルモデルも、自然キーを参照する外部キーによって妨害されません。実際、自然キーを参照すると、パフォーマンスが劇的に向上することがよくあります。必要な情報が自然なキーに完全に含まれている頻度に驚かれることでしょう。そのキーを参照すると、より広いテーブルの結合が行われます(したがって、1ページに保存できる行数が減ります)。

定義により、必要な情報はすべての「ルックアップ」テーブルの自然キーに常に完全に含まれています。(ルックアップテーブルという用語は非公式です。リレーショナルモデルでは、すべてのテーブルは単なるテーブルです。米国の郵便番号のテーブルには、{AK、Alaska}、{AL、Alabama}、{AZ、Arizona}のような行があります。 、など。ほとんどの人はこれをルックアップテーブルと呼びます。)

大きなシステムでは、複数の候補キーを持つテーブルを見つけることは珍しくありません。また、企業の一部にサービスを提供するテーブルが1つの候補キーを参照することも、企業の別の部分にサービスを提供するテーブルが別の候補キーを参照することも珍しくありません。これはリレーショナルモデルの長所の1つであり、SQLが十分にサポートしているリレーショナルモデルの一部です。

代理キーも持っているテーブルで自然キーを参照すると、2つの問題が発生します。

まず、人々を驚かせるでしょう。私は通常、「最小限のサプライズ原則」を強く主張しますが、これは驚くべき人々を気にしない1つの状況です。開発者が外部キーの論理的な使用に驚いているという問題がある場合、ソリューションは再設計ではなく教育です。

第二に、ORMは一般にリレーショナルモデルを中心に設計されておらず、ベストプラクティスを反映しない仮定が組み込まれている場合があります。(実際、データベースの専門家からの入力がなくても設計されていることが多いようです。)すべてのテーブルでID番号を要求することは、これらの仮定の1つです。もう1つは、ORMアプリケーションがデータベースを「所有」していることを前提としています。(したがって、テーブルと列を自由に作成、削除、および名前変更できます。)

私は、30年の間に少なくとも20以上の言語で書かれた数百のアプリケーションプログラムにデータを提供するデータベースシステムに取り組んできました。そのデータベースは、ORMではなくエンタープライズに属します。

重大な変更をもたらすフォークは、ショーストッパーである必要があります。

私が働いていた会社で、自然キーと代理キーの両方でパフォーマンスを測定しました。代理キーが自然キーよりも性能を発揮し始める転換点があります。(パーティショニング、部分インデックス、関数ベースのインデックス、追加のテーブルスペース、ソリッドステートディスクの使用など、自然なキーパフォーマンスを高く維持するための追加の労力を想定していません。)その間、自然キーを使用するとパフォーマンスが向上します。

その他の関連する回答:データベーススキーマの混乱


5

私がサロゲートキーをサポートする主な理由は、自然キーはしばしば変更される可能性があるため、すべての関連テーブルを更新する必要があり、サーバーにかなりの負荷がかかることを意味します。

さらに30年間、私は多くのトピックでさまざまなデータベースを使用してきましたが、真の自然なキーは非常にまれです。ものはおそらくユニーク(SSN)ではありません。特定の時点でユニークなものは後で非ユニークになる可能性があり、電子メールアドレスや電話番号のようなものはユニークかもしれませんが、それらは後で異なる人々に再利用できます日付。もちろん、人や企業の名前のような良い一意の識別子を持っていないものもあります。

自然キーを使用して結合を回避することに関して。はい、結合を必要としないselectステートメントを高速化できますが、int結合は一般に高速であるため、結合が必要な場所が遅くなります。また、おそらく挿入と削除が遅くなり、キーが変更されたときに更新のパフォーマンスの問題が発生します。複雑なクエリ(とにかく遅い)はさらに遅くなります。そのため、単純なクエリは高速ですが、レポート作成や複雑なクエリ、およびデータベースに対する多くのアクションが遅くなる可能性があります。それはバランスをとる行為であり、データベースのクエリ方法に応じて、何らかの方法で傾く可能性があります。

そのため、すべてに当てはまるワンサイズというものはありません。それは、データベースと、それがどのように照会され、どのタイプの情報がそこに保存されるかによって異なります。自分の環境で何が最適に機能するかを調べるには、テストを行う必要がある場合があります。


1
「…自然のキーはしばしば変更される可能性があります…」-それはあまり良いキーではありません!属性が頻繁に変更される場合は、それをキーとして使用しないでください(もちろん、「多くの場合」のさまざまな定義のため)。ファビアンパスカル、キーを選択するための4つの基準があると主張しました:親しみやすさ、既約性、安定性、シンプルさ。代理キーの単純さのためにこれらをトレードオフする場合があります。HLGEMが言ったように、「すべての答えに適合するサイズはありません。」
グリーンストーンウォーカー

1
@GreenstoneWalker、キーとしてそれを作るべきではないことに同意しますが、多くの場合、4つすべての基準に適合するキーを持っていないため、独自のものを選択する必要があります。そして、一意性がcopmpositeキーである場合、結合が必要な場合、パフォーマンスの点で問題はさらに大きくなる可能性があります。
HLGEM

-4

答えがわからない場合は、サロゲートを使用してください。理由は次のとおりです。ビジネスルールについて仮定が行われ、それらの仮定が間違っているか、ルールが変更された場合、データはゴミになります。以下に例を示します。

個人、ロール、PersonRole

現在のビジネスルールでは、Personには1つのロールがあります。PersonRole(PersonName、PersonBirthDate、PersonMotherMaidenName、...、RoleCode)のPersonとRoleをリンクするテーブルを作成します

Natural Keysに関して言えば、あなたは真の純粋主義者です!しかし、真剣に、組織が、ある人が複数の役割を引き受けることができると判断した場合はどうなりますか?ビジネスニーズの変化をサポートするダウンストリームの影響は何ですか?


2
そして、代理キーにこれらの問題はありませんか?方法を教えてください。
コリン 'ハート14

4
与えられた例は、議論に関連する何かを実証していないようです。
ムスタッチョ14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.