テーブル間の外部キーを自然キーまたは代理キーにリンクするかどうかのベストプラクティスはありますか?私が本当に見つけた唯一のディスカッション(私のgoogle-fuが欠けている場合を除く)は この質問でのジャックダグラスの回答 であり、彼の推論は私には聞こえます。ルールが変わることを超えた議論は承知していますが、これはどのような状況でも考慮する必要があることです。
質問の主な理由は、自然キーでFKを使用するレガシーアプリケーションがあるが、OR/M(この場合はNHibernate)に移動するための開発者からの強いプッシュがあり、フォークがすでにいくつかを生成しているためです変更を壊すので、自然なキーを使用してそれらをトラックに戻すか、FKのサロゲートキーを使用するようにレガシーアプリを移動します。私の直感は、元のFKを復元するように言っていますが、これが本当に正しい道なのかどうかは正直わかりません。
テーブルの大部分には既にサロゲートキーとナチュラルキーの両方が定義されているため(一意の制約とPKを使用)、列を追加する必要はありません。私たちはSQL Server 2008を使用していますが、これがどのDBにも十分汎用的であることを願っています。
SQLもリレーショナルモデルも、自然キーを参照する外部キーの影響を受けません。実際、自然キーを参照すると、パフォーマンスが劇的に向上することがよくあります。必要な情報が自然キーに完全に含まれている頻度に驚くでしょう。そのキーを参照すると、結合がより広いテーブルと交換されます(その結果、1ページに格納できる行数が減少します)。
定義により、必要な情報はalwaysであり、すべての「ルックアップ」テーブルの自然キーに完全に含まれています。 (用語lookup tableは非公式です。リレーショナルモデルでは、すべてのテーブルは単なるテーブルです。米国の郵便番号のテーブルには、次のような行がある場合があります。 :{AK、アラスカ}、{AL、アラバマ}、{AZ、アリゾナ}など。ほとんどの人はこれをルックアップテーブルと呼びます。)
大規模なシステムでは、複数の候補キーを持つテーブルを見つけることは珍しくありません。企業の一部にサービスを提供するテーブルが1つの候補キーを参照することや、企業の別の一部にサービスを提供するテーブルが別の候補キーを参照することも珍しくありません。これは、リレーショナルモデルの長所の1つであり、SQLがサポートするリレーショナルモデルの一部です。
サロゲートキーも持つテーブルでナチュラルキーを参照すると、2つの問題が発生します。
まず、人を驚かせるでしょう。私は通常 最小サプライズの原則 に対して強くロビー活動をしますが、これは私が驚くべき人々を気にしない1つの状況です。問題が外部キーの論理的な使用に開発者が驚いていることである場合、解決策は再設計ではなく教育です。
第2に、ORMは一般的にリレーショナルモデルを中心に設計されておらず、ベストプラクティスを反映しない仮定を具体化する場合があります。 (実際には、データベースの専門家からの入力なしに設計されていることがよくあります。)すべてのテーブルにID番号を要求することは、これらの前提の1つです。もう1つは、ORMアプリケーションがデータベースを「所有」していると想定しています。 (したがって、テーブルと列を自由に作成、削除、および名前変更できます。)
私は、30年間で少なくとも24の言語で書かれた何百ものアプリケーションプログラムにデータを提供するデータベースシステムに取り組んできました。そのデータベースは、ORMではなく企業に属しています。
重大な変更を導入するフォークはショーストッパーである必要があります。
勤務先の会社で、ナチュラルキーとサロゲートキーの両方でパフォーマンスを測定しました。サロゲートキーが自然キーよりも優れたパフォーマンスを発揮する転換点があります。 (パーティション分割、部分インデックス、関数ベースのインデックス、追加のテーブルスペース、ソリッドステートディスクの使用など、自然なキーパフォーマンスを高く維持するための追加の追加の努力を仮定すると、など)その会社の私の推定では、2045年頃にその転換点に到達します。その間、自然なキーを使用するとパフォーマンスが向上します。
その他の関連する回答: データベーススキーマの混乱
サロゲートキーをサポートする主な理由は、自然キーは変更されることが多いため、関連するすべてのテーブルを更新する必要があるため、サーバーにかなりの負荷がかかる可能性があるためです。
さらに30年の間に、多くのトピックについてさまざまなデータベースを使用してきましたが、実際の自然キーはかなりまれであることがよくあります。一意と思われるもの(SSN)は一意ではなく、特定の時点で一意であるものは後で一意でなくなる可能性があり、メールアドレスや電話番号などの一部は一意である可能性がありますが、後で別のユーザーに再利用できます日付。もちろん、人や企業の名前のように、適切な一意の識別子がないものもあります。
自然キーを使用して結合を回避することについて。はい、結合を必要としないselectステートメントを高速化できますが、int結合は一般的に高速であるため、結合が必要な場所が遅くなります。また、挿入と削除が遅くなり、キーが変更されると、更新時にパフォーマンスの問題が発生します。複雑なクエリ(とにかく遅い)はさらに遅くなります。そのため、単純なクエリはより高速ですが、レポート作成や複雑なクエリ、およびデータベースに対する多くのアクションが遅くなる可能性があります。これはバランスをとる行為であり、データベースのクエリ方法に応じて、いずれかの方向に傾く可能性があります。
したがって、1つのサイズですべての答えに当てはまるわけではありません。それはあなたのデータベースとそれがどのように照会されるか、そしてどのタイプの情報がそこに格納されるかに依存します。自分の環境で何が最適に機能するかを確認するために、いくつかのテストを行う必要がある場合があります。