テーブルの主キーのベストプラクティスは何ですか?


256

テーブルを設計するとき、一意であり、主キーにする1つの列を持つ習慣を身につけました。これは、要件に応じて3つの方法で実現されます。

  1. 自動インクリメントするID列。
  2. 一意の識別子(GUID)
  3. 行ID列として機能できる短い文字(x)または整数(またはその他の比較的小さな数値型)列

数値3は、かなり小さなルックアップに使用されます。主に、一意の静的な長さの文字列コード、または年やその他の数値などの数値を持つテーブルを読み取ります。

ほとんどの場合、他のすべてのテーブルには、自動インクリメント整数または一意の識別子の主キーがあります。

質問 :-)

私は最近、一貫した行識別子がなく、主キーが現在さまざまな列にわたってクラスター化されているデータベースでの作業を開始しました。いくつかの例:

  • 日時/文字
  • 日時/整数
  • datetime / varchar
  • char / nvarchar / nvarchar

これに有効なケースはありますか?私は常にこれらのケースのためにアイデンティティまたは一意の識別子の列を定義していたでしょう。

さらに、主キーがまったくない多くのテーブルがあります。これの正当な理由がある場合、それは何ですか?

テーブルが設計どおりに設計された理由を理解しようとしていますが、それは私にとって大きな混乱のように見えますが、それには十分な理由があったのかもしれません。

答えを解読するのに役立つ3番目の質問:複合主キーを構成するために複数の列が使用されている場合、代理キー/人工キーと比較して、この方法には特定の利点がありますか?主にパフォーマンス、メンテナンス、管理などについて考えていますか?


データベーススキル:主キーを選択するための健全なアプローチ」が適切な読み物であることがわかり、概説したほとんどのポイントに従います。
user2864740

回答:


254

私はいくつかのルールに従います:

  1. 主キーは必要なだけ小さくする必要があります。数値型は文字形式よりもはるかにコンパクトな形式で格納されるため、数値型を優先します。これは、ほとんどの主キーが別のテーブルの外部キーであり、複数のインデックスで使用されるためです。キーが小さいほど、インデックスが小さくなり、使用するキャッシュ内のページが少なくなります。
  2. 主キーは変更しないでください。主キーの更新は常に問題外です。これは、複数のインデックスで使用され、外部キーとして使用される可能性が最も高いためです。単一の主キーを更新すると、変更の波及効果が生じる可能性があります。
  3. 論理モデルの主キーとして「問題のある主キー」を使用しないでください。たとえば、パスポート番号、社会保障番号、または従業員の契約番号(これらの「主キー」は実際の状況では変わる可能性があるため)。

代理キーと自然キーについては、上記のルールを参照します。自然キーが小さく、決して変更されない場合、それを主キーとして使用できます。自然キーが大きいか、変更される可能性がある場合は、代理キーを使用します。主キーがない場合でも、サロゲートキーを作成します。これは、経験上、常にスキーマにテーブルを追加し、主キーを配置したいと考えているためです。


3
私はそれが好きです!「ルール」の基礎となる文書はありますか?ありがとう!
ロイドコットン

4
いいえ、ただの経験です。「小さな」データベースを扱う場合、このことはそれほど重要ではありません。しかし、大きなdbを扱う場合、重要なことはすべて重要です。テキストまたはGUIDを使用する場合と比較して、整数または長いpkを含む行が10億ある場合を想像してみてください。大きな違いがあります!
ロジカルマインド2008

44
人工キーを使用する場合は、その一意のインデックスを自然キー(実際に存在する場合は多くの場合そうではない場合があります)に配置することを忘れないでください。
HLGEM 2008

3
@Lloyd Cotten:ビッグデータエンジンプロバイダーがルール番号1をサポートするために次のように言っています:skyfoundry.com/forum/topic/24Ints に戻ることを私は確信しました
ホブ

4
「自然な鍵は小さく、決して変わらない」ことを「知っている」としても、よく考えてください。「これらのコードを再利用することはありません」は有名な最後の言葉です。「この内部ブランドの2文字の表現は何か」など...「それが変わることはない」と仮定する前に、データベースの再構築から離れて1つの財務上の決定をすることを2度考えます。
Andrew Hill

90

自然の詩と人工の鍵は、データベースコミュニティの間で一種の宗教的な議論になっています。この記事とリンクされている他の記事を参照してください。私は常に人工的な鍵を持っていることも、それらを決して持たないことも好きではありません。私はケースバイケースで決定します、例えば:

  • 米国の州:テキサスのstate_id = 1ではなく、state_code(テキサスの「TX」など)を使用します
  • 従業員:他に機能するものを見つけるのが難しいため、私は通常、人工的なemployee_idを作成します。SSNまたは同等のものは機能する可能性がありますが、SSNをまだ提供していない新しい参加者などの問題が発生する可能性があります。
  • 従業員の給与履歴:(employee_id、start_date)。私は考えていない人工employee_salary_history_idを作成します。どのような点で役立ちますか(「愚かな一貫性」以外)

人工キーが使用される場合は常に、自然キーに対する一意の制約も常に宣言する必要があります。たとえば、必要な場合はstate_idを使用しますが、state_codeに一意の制約を宣言する方が適切です。そうでない場合、最終的には次のようになります。

state_id    state_code   state_name
137         TX           Texas
...         ...          ...
249         TX           Texas

9
SQL Server 2005/2008では、自然(テキスト)キーがintキーよりも高速な場合があります。私は、主キーとして使用する7〜8文字のフレンドリーなコードを備えたアプリを持っています。これは、intサロゲートよりも高速で(多くの場合、より便利です)。とにかくコードを必要とするため、人が読める/記憶できるコードを作成し、競合することなく別のアプリケーションインスタンス(複数のサイトがより大きなサイトに集約される)に安全に転送できます。
lambacck、2011年

1
+1良い答え。しかし、私は人事担当者を従業員IDの信頼できるソースにするようにします。つまり、SSNなどのIDを使用する可能性があり、参照を取り上げる可能性が高い実際の従業員の検証を担当する担当者です。人事部門は、 DBMSではなく、従業員IDのソース!
onedaywhen

@ onedaywhen-しません。人事担当者を信頼してください。人々は去り、新しい人がやって来て、異なるアイデアを持っています。一意であると思われる識別子へのアクセスを提供します/使用したいのですが、内部的にはdbaが独自の決定を下す必要があります
Dave Pile

1
SSNは必ずしもすべての国で一意ではないことに注意してください。少なくともオーストリアでは、複数の人々が同じ数を共有する可能性があります
maja 2017

また、一部の国(米国でもそうだと思います)では、実際にはSSNを共有しないことを推奨しています。
Stijn de Witt

25

見落とされがちなものについての追加コメントです。場合によっては、代理キーを使用しないことが子テーブルでメリットがあります。たとえば、1つのデータベース内で複数の企業を実行できるように設計されているとします(おそらく、それがホスト型ソリューションであるか、何でもかまいません)。

次のテーブルと列があるとします。

Company:
  CompanyId   (primary key)

CostCenter:
  CompanyId   (primary key, foreign key to Company)
  CostCentre  (primary key)

CostElement
  CompanyId   (primary key, foreign key to Company)
  CostElement (primary key)

Invoice:
  InvoiceId    (primary key)
  CompanyId    (primary key, in foreign key to CostCentre, in foreign key to CostElement)
  CostCentre   (in foreign key to CostCentre)
  CostElement  (in foreign key to CostElement)

最後のビットが意味をなさない場合Invoice.CompanyId、1つはCostCentreテーブルに対するもので、もう 1つはCostElementテーブルに対するものです。主キーは(InvoiceIdCompanyId)です。

このモデルでは、ある会社のCostElementと別の会社のCostCentreを台無しにして参照することはできません。代理キーがオンに使用された場合CostElementCostCentreテーブル、それは次のようになります。

失敗する機会が少ないほど良いです。


6
これは、代理キーを使用する場合の欠点です。テーブルに代理キーがある場合でも、これらの種類の制約に使用できます。残念ながら、制約にはインデックスが必要ですが、(surrogate_key)がそれ自体で一意である場合、(surrogate_key、other_column)に一意のインデックスを作成するのは奇妙です。また、(surrogate_key)は外部テーブルで一意であるため、(other_column)はマップテーブルで完全に冗長になることがよくあります。サロゲートは本当に物事を台無しにすることができます。
Samuel Danielson、2010年

24

自然キーの使用は、1つの単純な理由(人為的エラー)で回避します。多くの場合、自然な一意の識別子(SSN、VIN、アカウント番号など)を使用できますが、人間がそれらを正しく入力する必要があります。SSNを主キーとして使用している場合、データ入力中に誰かがいくつかの数値を転置し、エラーがすぐには検出されない場合、主キーの変更に直面します。

私の主キーはすべてバックグラウンドでデータベースプログラムによって処理され、ユーザーはそれらに気づくことはありません。


1
私は、主キーとしてSSNまたは納税者番号を使用するいくつかのデータベースを使用しました。ストレージと外部キー参照に関しては非効率的です。人の社会保障番号は変更できることは言うまでもありません。だから私は完全にあなたに同意します。
Alex Jorgenson、2013

13

さまざまなフィールドから主キーを作成することに問題はありません。それが自然キーです。

Identity列(候補フィールドの一意のインデックスに関連付けられている)を使用して、代理キーを作成できます。

それは古い議論です。ほとんどの場合、代理キーを使用します。

しかし、鍵がないという言い訳はありません。

RE:編集

ええ、それについては多くの論争があります:D

自然なキーが自然な選択であるという事実を除けば、自然なキーには明らかな利点はありません。idPersonの代わりに常にName、SocialNumberなどを考えます。

サロゲートキーは、自然キーが持ついくつかの問題(たとえば、伝播する変更)に対する答えです。

サロゲートに慣れると、よりクリーンで管理しやすくなります。

しかし、結局のところ、それは好みの問題、つまり考え方の問題であることがわかります。人々は自然な鍵で「よりよく考える」ことができ、他の人はそうではありません。


13
人々は自然な鍵で「よく考える」。機械とデータベースはそうではありません。
FDCastel 2009年

11

テーブルには常に主キーが必要です。そうでない場合は、AutoIncrementフィールドである必要があります。

大量のデータを転送し、(データベースによっては)プロセスの速度が低下する可能性があるため、主キーが省略される場合があります。ただし、その後に追加する必要があります。

リンクテーブルに関するいくつかのコメント、これは正しい、これは例外ですが、整合性を保つためにフィールドはFKである必要があります。また、リンクの複製が許可されていない場合、これらのフィールドも主キーになる可能性があります...しかし、例外はプログラミングでよくあるものであるため、単純な形式です。データの整合性を維持するために、主キーが存在する必要があります。


同意する。また、大量のデータを挿入する場合は、主キー制約を削除して(またはTSQLでINSERT IDENTITY ONを使用して)後で元に戻します:)
Andrew Rollings

1
例外があります。リンクテーブルは明らかに
annakata 2008

別の理由:PK /一意のキーがない場合、テーブルブラウザー(つまり、Access / SQL Server Management Studioなど)は、重複した行を持つ単一の行の更新/削除を拒否します。そのためにSQLを作成する必要があります。
デニスC

データウェアハウスのファクトテーブルからPKを省略することはよくあることです。Oracleでは、ROWID疑似列を一意の識別子として短期的に参照できます(つまり、どこかに保存せず、変更されないことを期待します)
David Aldridge

9

これらすべての良い答えに加えて、私が読んだばかりの優れた記事「素晴らしい主キーの議論」を共有したいだけです。

いくつかのポイントを引用するだけです:

開発者は、各テーブルの主キーを選択するときにいくつかのルールを適用する必要があります。

  • 主キーは、各レコードを一意に識別する必要があります。
  • レコードの主キー値をnullにすることはできません。
  • 主キー値は、レコードの作成時に存在している必要があります。
  • 主キーは安定している必要があります。主キーフィールドは変更できません。
  • 主キーはコンパクトで、可能な限り少ない属性を含む必要があります。
  • 主キーの値は変更できません。

自然キー(傾向がある)はルールに違反します。代理キーはルールに準拠しています。(あなたはその記事をよく読んでください、それはあなたの時間の価値があります!)


7

主キーの何が特別ですか?

スキーマ内のテーブルの目的は何ですか?テーブルのキーの目的は何ですか?主キーの何が特別ですか?主キーに関する議論は、主キーがテーブルの一部であり、そのテーブルがスキーマの一部であるという点を逃しているようです。テーブルとテーブルの関係に最適なものが、使用されるキーを駆動する必要があります。

テーブル(およびテーブルの関係)には、記録する情報に関する情報が含まれています。これらの事実は、自己完結的で、意味があり、容易に理解でき、矛盾しないものでなければなりません。設計の観点からは、スキーマに追加またはスキーマから削除された他のテーブルは、問題のテーブルに影響を与えるべきではありません。情報だけに関連するデータを保存する目的がなければなりません。テーブルに何が格納されているかを理解するには、科学的研究プロジェクトを行う必要はありません。同じ目的で保存されたファクトを複数回保存することはできません。キーは一意の記録される情報の全体または一部であり、主キーは、テーブルへの主アクセスポイントとなる特別に指定されたキーです(つまり、挿入だけでなく、データの一貫性と使用方法のために選択する必要があります)パフォーマンス)。

  • サイド:アプリケーションプログラマー(私は時々)が設計および開発しているほとんどのデータベースの残念な副作用は、アプリケーションまたはアプリケーションフレームワークに最適なものが、テーブルの主キーの選択を左右することが多いということです。これにより、整数およびGUIDキー(アプリケーションフレームワークで簡単に使用できるため)とモノリシックテーブルデザイン(メモリ内のデータを表すために必要なアプリケーションフレームワークオブジェクトの数が減るため)が生まれます。これらのアプリケーション主導のデータベース設計の決定は、大規模に使用すると、データの一貫性に関する重大な問題を引き起こします。この方法で設計されたアプリケーションフレームワークは、当然、一度に1つのテーブルを設計します。「部分的なレコード」はテーブルに作成され、時間の経過とともにデータが入力されます。アプリケーションが正しく機能しない場合、マルチテーブルの相互作用が回避されるか、使用するとデータの一貫性が失われます。これらの設計は、意味のない(または理解が難しい)データ、テーブルに広がるデータ(現在のテーブルを理解するために他のテーブルを参照する必要があります)、および重複データにつながります。

主キーは必要なだけ小さくする必要があると言われていました。キーは必要なだけ大きくすべきだと私は言うでしょう。無意味なフィールドをテーブルにランダムに追加することは避けてください。ランダムに追加された無意味なフィールドからキーを作成するのはさらに悪いことです。特に、別のテーブルから非主キーへの結合依存関係が破壊される場合はなおさらです。これは、テーブルに適切な候補キーがない場合にのみ妥当ですが、これがすべてのテーブルに使用された場合、スキーマ設計が不十分であることを示しています。

また、主キーの更新は常に問題外であるため、主キーを変更しないでください。ただし、更新は削除とそれに続く挿入と同じです。このロジックでは、1つのキーを持つテーブルからレコードを削除してから、2番目のキーを持つ別のレコードを追加しないでください。代理主キーを追加しても、テーブルに他のキーが存在するという事実は削除されません。テーブルの非主キーを更新すると、サロゲートキーを介して他のテーブルがその意味に依存している場合(たとえば、ステータスの説明が「処理済み」から「キャンセル済み」に変更されたサロゲートキーを持つステータステーブル)、データの意味が破壊される可能性があります'間違いなくデータが破損します)。常に問題とすべきではないのは、データの意味を破壊することです。

そうは言っても、今日のビジネスに存在する多くの不適切に設計されたデータベース(無意味な代理キー付きデータ破損-1NF巨人)には感謝しています。これは、適切なデータベース設計を理解している人々に無限の労力が費やされることを意味します。 。しかし、悲しいことに、それは時々私をシーシュポスのように感じさせますが、私は彼が401kの1つの問題を抱えていたと思います(クラッシュ前)。重要なデータベース設計の質問については、ブログやWebサイトから離れてください。データベースを設計している場合は、CJ Dateを検索してください。Celko for SQL Serverを参照することもできますが、それは最初に鼻をかざした場合に限られます。Oracle側では、Tom Kyteを参照してください。


1
「このロジックにより、1つのキーを持つテーブルからレコードを削除してから、2番目のキーを持つ別のレコードを追加することはできません。」-これにはケースがあり、それが外部キーの "ON DELETE RESTRICT"句が実際に行うことです。場合によっては(監査証跡が必要な場合など)、「削除された」ブール値フィールドは、レコードの削除を許可するよりも優れています。
Waz

6

利用できる場合は、通常、自然キーが最適です。したがって、datetime / char が行を一意に識別し、両方の部分が行にとって意味がある場合、それは素晴らしいことです。

datetimeだけが意味を持ち、charを追加して一意にする場合は、identifyフィールドを使用することもできます。


9
通常最高ですか?私には科学的な根拠はありませんが、ほとんどの人が自然よりも代理キーを好むということはほぼ間違いありません。多くの場合、自然な鍵はありません。
JC。

3
データベース内の行には常に自然キーが存在する必要があります。その「自然な」キーは、ビジネスの世界または技術システムによって生成されたものである可能性がありますが、常に存在する必要があります。
トムH

2
あなたの世界では、それがテーブル内の行を識別する唯一の方法であると判断された場合、そうです。もちろん、設計者がPKのGUIDを作成することを選択した場合、それは通常、実際の自然キーを見つけるための作業を行っていないためです。その場合、GUIDは自然キーではありません。
トムH

8
2.自然界から鍵を取り出すと、自然界が変化して鍵が壊れます。電話番号を使用すると、同じ世帯から2人のユーザーを取得できます。姓を使用すると、結婚します。SSNを使用すると、プライバシー法が変更され、削除する必要があります。
James Orr

2
@バリー:RE:#2。自然界が変化し、それによって自然キーが変化する場合は、自然キーの選択がうまくいっていないことを意味します。当然のことながら、自然キーは時間の経過とともに変化しません。
トムH

6

これは、25年以上の開発経験の後に解決した経験則です。

  • すべてのテーブルには、自動インクリメントする単一列の主キーが必要です。
  • 更新可能であることを意図した任意のビューに含める
  • 主キーは、アプリケーションのコンテキストでは何の意味も持ちません。つまり、SKU、アカウント番号、従業員ID、またはアプリケーションにとって意味のあるその他の情報であってはなりません。これは、エンティティに関連付けられた一意のキーにすぎません。

主キーは、最適化の目的でデータベースによって使用され、特定のエンティティの識別または特定のエンティティに関連すること以外の目的でアプリケーションによって使用されるべきではありません。

常に単一の値の主キーを持つことで、UPSERTの実行が非常に簡単になります。

追加のインデックスを使用して、アプリケーションで意味を持つ複数列のキーをサポートします。


5

私にとって自然キーと人工キーは、データベースに必要なビジネスロジックの量の問題です。社会保障番号(SSN)はその良い例です。

「私のデータベースの各クライアントは、SSNを持つことになります。Bam、完了、それを主キーにして、それで完了です。ビジネスルールが変更されると、やけどを負うことを忘れないでください。

私はビジネスルールを変更した経験があるため、自分ではナチュラルキーが好きではありません。ただし、変更されないことが確実な場合は、いくつかの重要な結合が妨げられる可能性があります。


8
また、SSNが一意である必要があるにもかかわらず、一意ではないデータを確認しました。別のソースからデータをインポートする場合は、自然キーに十分注意してください。
HLGEM 2008

2
個人情報の盗難の対象となっている場合は、社会保障番号を変更することができます。それらがあなたの数を変える4つの状況がさらにあり、それらはssa.govサイトにリストされています。
Zvi Twersky 2016

4

元のデータ構造の設計者には、Steven A. Loweの丸めた新聞療法が必要だと思います。

余談ですが、主キーとしてのGUIDはパフォーマンスを独占する可能性があります。私はそれをお勧めしません。


2
そのパフォーマンスの独占は、時期尚早な最適化と言えます。場合によっては、GUIDが必要です(切断されたクライアント、将来のテーブルのマージ、レプリケーション)
JC。

2
「時期尚早の最適化」は、SO(IMHO)では使い古されたフレーズです。はい、GUIDが必要な場合もありますが、Andrewは、必要かどうかにかかわらず、デフォルトのデータ型として使用しないでください。
Tony Andrews、

OK、実際には時期尚早の最適化ではありませんでした。つまり、ほとんどの人はパフォーマンスの違いに気付くために必要なボリュームを経験していません。はい。GUIDが不要になることがわかっている場合は、自動インクリメントを使用してください。
JC。

または両方を使用します。すばやい選択と結合のためのint / longベースの主キーを用意し、次にGUIDフィールドを用意します。少なくとも、それは私がやっていることです。これは間違っていますか?私はそれをしてはいけませんか?:)
Andrew Rollings

両方の列も使用しています。しかし、それが間違っているかどうかはわかりません。あなたはそれを@AndrewRollingsで見つけましたか?
ヨギ

3

複数のフィールドで構成される「複合」または「複合」主キーを使用する必要があります。

これは完全に許容できる解決策です。詳細についてはここにアクセスしてください:)


3

私も常に数値のID列を使用しています。Oracleでは、私はnumber(18,0)を使用しますが、number(12,0)(またはlongではなくintであるもの)以上の実際の理由はありません、おそらく数十億行になることを心配したくないだけですdb!

また、基本的な追跡用に作成および変更された列(タイムスタンプタイプ)も含めています。

列の他の組み合わせに一意の制約を設定してもかまいませんが、ID、作成、変更されたベースライン要件が本当に気に入っています。


2
また、データを含むテーブルにのみ、リンク/結合テーブルにIDを配置しないことも指摘する必要があります。
JeeBee 2008

3

自然な主キーを探して、可能な限り使用します。

自然なキーが見つからない場合、SQL Serverはツリーを使用するため、INT ++よりもGUIDを使用します。ツリーの末尾に常にキーを追加することは好ましくありません。

多対多の結合であるテーブルでは、外部キーの複合主キーを使用します。

SQL Serverを使用できるほど幸運なので、プロファイラーとクエリアナライザーを使用して実行計画と統計を調査し、キーが非常に簡単に実行されていることを確認できます。


このステートメントをバックアップするためのドキュメントはありますか?「SQL Serverはツリーを使用しているため、自然なキーが見つからない場合、INT ++よりもGUIDを使用します。ツリーの末尾に常にキーを追加することは悪いことです。」懐疑的ではなく、いくつかのドキュメントをコンパイルしようとしています。
ロイドコテン

1
@ロイド-あなたが私が非常に魅力的だと思う何かに興味を持ってくれてうれしいです。得意起点msdn.microsoft.com/en-us/library/ms177443(SQL.90).aspx
なGuge

2

私は常に自動番号またはIDフィールドを使用します。

私はSSNを主キーとして使用していたクライアントで働いていましたが、HIPAA規制により「MemberID」への変更が強制され、関連するテーブルの外部キーを更新するときに大量の問題が発生しました。ID列の一貫した基準を守ることは、すべてのプロジェクトで同様の問題を回避するのに役立ちました。


6
開発者による自然キーの選択が悪いからといって、自然キーが悪いというわけではありません。
トムH

1
使いにくいツールは、どういうわけかそのツールに対するポイントではありませんか?
Sqeaky

1

すべてのテーブル主キーがです。それ以外の場合は、HEAPを使用します。これは、状況によっては、必要な場合があります(データがService Brokerを介して別のデータベースまたはテーブルにレプリケートされるときに、挿入負荷が高くなります)。

行の量が少ないルックアップテーブルの場合、INTよりも場所が取られないため、主キーとして3 CHARコードを使用できますが、パフォーマンスの違いは無視できます。それ以外は、関連付けられたテーブルの外部キーで構成された複合主キーを持つ参照テーブルがない限り、常にINTを使用します。


1

この古くからある議論の前後をすべて読みたい場合は、Stack Overflowで「ナチュラルキー」を検索してください。結果のページを取得する必要があります。


1

GUIDは主キーとして使用できますが、適切に実行するには、適切なタイプのGUIDを作成する必要があります。

COMB GUIDを生成する必要があります。それとパフォーマンス統計に関する優れた記事は 、主キーとしてのGUIDのコストです

また、SQLで COMB GUIDを作成するコードの一部は、Uniqueidentifierとidentityarchive)にあります。


5
私見、GUIDは、データベース間でデータを同期する必要がある場合にのみ使用してください。自動生成されたIDには問題があります。GUIDを使用することと基本的な数値型を使用することの違いは、GUIDは行ごとに16バイトを必要とし、数値ははるかに小さいことです。
ロジカルマインド2008

上記で提供したリンクにアクセスしても、COMB GUIDを使用した場合のパフォーマンスの違いはほとんどありません。
Donny V.

0

私たちは多くの結合を行い、複合主キーはパフォーマンスを独占しています。2番目の候補キーを導入する場合でも、単純なintまたはlongは多くの問題を処理しますが、3つのフィールドではなく1つのフィールドで結合する方がはるかに簡単で理解しやすくなっています。


1
複合キーが伝達されなかったために必要な実際の2つのテーブルを結合するために6つのテーブルをトラバースする必要がある場合、この戦略は崩れます。また、複数の挿入にループ/カーソルを使用する必要があり、パフォーマンスが非常に高くなる可能性があります。
トムH

2
私は何か新しいことを学ぶのにそれほど大きくありません。私はあなたが言っていることの例を見たいと思います、これらの宗教的議論のいくつかに少し合理的な事実を注入することは役に立ちます。
ダン・ブレア

0

私は自然キーの設定について前向きに考えます。データベース管理の作業が非常に簡単になるので、可能な限りそれらを使用してください。私は、すべてのテーブルに次の列があるという基準を社内で確立しました。

  • 行ID(GUID)
  • 作成者(文字列;現在のユーザーの名前のデフォルトがあります(SUSER_SNAME()T-SQLの場合))
  • 作成(DateTime)
  • タイムスタンプ

行IDにはテーブルごとに一意のキーがあり、いずれの場合も行ごとに自動生成され(アクセス許可によって誰も編集できないようになっています)、すべてのテーブルとデータベース全体で一意であることが合理的に保証されています。ORMシステムが1つのIDキーを必要とする場合、これが使用されます。

一方、実際のP​​Kは、可能であれば、自然なキーです。私の内部ルールは次のようなものです:

  • People-代理キー(INTなど)を使用します。内部の場合は、Active DirectoryユーザーGUIDを使用できます
  • ルックアップテーブル(StatusCodesなど)-短いCHARコードを使用します。INTよりも覚えやすく、多くの場合、紙のフォームとユーザーは簡潔にするためにそれを使用します(たとえば、Status = "E"は "Expired"、 "A"は "Approved"、 "NADIS"は "No Asbestos Detected"サンプル中)
  • リンクテーブル-FKの組み合わせ(例EventId, AttendeeId

したがって、理想的には、自然で人間が読み取り可能で記憶に残るPKと、ORMフレンドリーなテーブルごとの1つのID GUIDが得られることになります。

警告:私が維持しているデータベースは、数百万または数十億ではなく10万件のレコードになる傾向があるため、私の助言を禁ずる大規模なシステムの経験がある場合は、遠慮なく私を無視してください!


1
強力な自然キーのないテーブルの両方GUID INT SK を作成することを提案していますか?

必須ではありませんが、利点は次のとおりです。a)必要に応じて複製が簡単になる、b)ORMを処理するときに、オブジェクトを保存する前にコードでオブジェクトに一意のIDを割り当てることができる(これは、保存する前に、オブジェクトを何度も編集する必要があります(セッションキャッシュに保存するなど)。キーは、このインスタンスのINTです。GUIDは単なるボーナスです。
キースウィリアムズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.