代理キーと自然キー/ビジネスキーの比較[終了]


173

ここで再び行きます、古い議論はまだ起こります...

ビジネスキーを主キーとして使用した方がよいでしょうか、それとも、ビジネスキーフィールドに一意の制約がある代理ID(つまり、SQL Server ID)を使用した方がよいでしょうか。

理論を裏付ける例や証拠を提示してください。


24
@Joachim Sauer:物事が主観的であるかどうかについての議論は、それが問題の物事の客観性または主観性に何らかの方法で関係することなく、それ自体主観的である可能性があります。あなたが何かを客観的にする正確な客観的基準を述べる準備ができていない限り。ひげを作るのに必要な髪の毛の数など、「オープンコンセプト」と呼ばれるものがあります。あごの毛がない人はひげがなく、1インチの長さが5,000毛の人はひげがあると客観的に言うことができますが、客観的な決定を行うには中間のどこかに主観的な判断が必要です。
ErikE 2010

@Manrico:これを自問する必要があります。代理キーを使用しない場合でも、主キーは不変ですか?答えが「いいえ」の場合は、代理キーの使用を真剣に検討する必要があります。また、主キーの一部がユーザー入力から構成されている場合は、代理キーの使用を検討する必要があります。どうして?データ異常の危険があるため。
code4life 2016年

@TylerRickしかし、これは完全に良い質問ではありません。質問者が完全に認識している「宗教戦争」で証明されているように、明らかに解決策がない場合、それは一般的にすべての状況に適用できる解決策を求めます(引用:「ここでもう一度、古い議論がまだ起こります。 .. ")。世界が変わったかどうか疑問に思って、最後に一方を常に選択する説得力のある理由が提供されたのではなく、具体的な状況ごとにこの質問を何度も繰り返し続け、確信が持てない場合はSOに投稿することをお勧めします。これは独断主義を誘発するだけです。
MarioDS

回答:


96

両方とも。ケーキを持って食べなさい。

そのようにラベル付けされていることを除いて、主キーについて特別なことは何もないことに注意してください。これは、NOT NULL UNIQUE制約に過ぎず、テーブルには複数の制約を設定できます。

代理キーを使用する場合でも、ビジネスルールに従って一意性を確保するビジネスキーが必要です。


7
複数の「候補」キー(フィールドまたはNULLでない一意のフィールドの同じサイズのコレクション)がある場合は、ボイス・コッド正規形に違反している可能性があります。BCNFは3NFを超えているため、心配する人は多くありません。ただし、BCNFにいることが非常に役立つ状況もあります。
アラン

2
同意した。本当の質問は次のとおりです:テーブルに一意の代理キーを追加する必要がありますか?まったく別の問題は、論理主キーに何を使用するかです。どちらも本質的にはnull以外の一意のインデックス制約です。
dkretz 2009

1
「すべての問題は別のレベルの間接参照で解決されます」...サロゲートキーはそれだけです。別の間接レベル
スティーブシュネップ2009年

5
多くのコメントが、代理キーなしでは関係を設定できないと主張しているように見えるのは奇妙だと思います。多くの場合、代理キーは不要です。価値をもたらさないが技術的な負債を追加するものを追加する理由(そして場合によっては、他に類を見ない結果が突然非一意になる)。
Wil Moore III、

2
これはNOT NULL UNIQUE制約以上のものです。主キーは、データの物理的な順序を決定するクラスター化インデックスとして使用されます。一般に、Integerはシーケンシャルにインクリメントされ、データがディスク上のEOFに追加されるため、バランスが容易です。テキストやGUID(UUID)などの連続性の低いデータを使用すると、インデックスのバランスを取るためのディスクIOと労力が大幅に増加します。これは一種の大きな違いだと思います
Jin

124

代理キーを使用するいくつかの理由:

  1. 安定性:ビジネスまたは自然なニーズのためにキーを変更すると、関連するテーブルに悪影響を及ぼします。値に関連付けられている意味がないため、代理キーを変更する必要はほとんどありません。

  2. 規則:PKのさまざまな名前でテーブルを結合する方法を考える必要がなく、標準化された主キー列の命名規則を使用できます。

  3. 速度:PK値とタイプに応じて、整数のサロゲートキーは小さくなり、インデックス付けと検索が高速になります。


2
さて、サロゲートキーとナチュラルキーについてたくさん読んだ後、サロゲートキーを使用する方が良いと思います。しかし、私のデータベースでは、自然キー(NVARCHAR(20))は一意である必要があります。挿入ごとに(NOT NULL UNIQUE制約を使用して)値を繰り返さないようにその列のすべてのデータを確認する必要がある場合に、速度を上げる方法がわかりません。
VansFannel 2016年

70

非サロゲート(私は「自然な」と言うのをためらう)キーをサポートするためにまだ誰も何も言っていないようです。だからここに行く...

サロゲートキーの欠点は、それらが意味をなさないことです(一部では利点として引用されていますが...)。これにより、必要以上に多くのテーブルをクエリに結合しなければならない場合があります。比較:

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

に対して:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

誰もが真剣に次のことは良い考えだと思っていない限り:

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

「しかし」誰かが言うだろう、「MYPROJECTまたはVALIDまたはHRのコードが変更されるとどうなりますか?」私の答えは、「なぜ変更する必要があるのか​​」です。これらは、一部の外部の身体が今後「有効」を「良好」として再コード化する必要があるという法律を制定しようとしているという意味で、「自然な」キーではありません。「自然な」鍵のほんのわずかな割合のみが実際にそのカテゴリーに該当します-SSNと郵便番号が通常の例です。Person、Addressなどのテーブルには無意味な数値キーを使用しますが、すべての目的には使用できません。これは、なぜかほとんどの人が主張しているようです。

参照:別の質問に対する私の回答


14
主キーとしての-1自然キーには、子テーブルごとに、(代理キーの場合は1つだけではなく)複数のフィールドで構成される親のキーと子を追加する必要があるという問題があります。キー。したがって、TABLEAから開始して次の関係を想像してみてください。関係は1-0 .. *です。問題がわかりましたか?親キーは子テーブルに反映されます。TABLEAの主キーが変更されるとどうなりますか?次に、すべての子テーブルPKもリファクタリングする必要があります。
アルフレドオソリオ

9
@アルフレド:はい、もちろんトレードオフがあります。ただし、20年以上の経験では、テーブルのPK変更の定義を見たことはほとんどありません。定期的に発生する場合は、おそらく自然なキーも避けます。実際には、これが発生する非常にまれな状況で、私は拡大した影響の影響を受ける準備ができています。
トニーアンドリュース

10
同意しません。自然なキーを編集する必要があることを外部組織(顧客)が法制化し、システム全体に伝達することがよくあります。これは定期的に発生します。キーを変更する必要がないことを確認できる唯一の方法は、定義上意味がない場合です。さらに、最新のデータベースは内部結合を非常に効率的に処理するので、サロゲートを使用することによる潜在的に大きなスペースの増加は、多くの内部結合を実行する必要がないという利点を上回ります。
TTT

8
@TTT:そもそもデザインは弱いものでした。繰り返しになりますが、ここで男性と男の子が区別されます。自然な鍵をいつ使用するか、および代理をいつ使用するかを適切に選択します。あなたはそれを一般的な教義としてではなく、テーブルごとに決定します。
DanMan 2013年

7
また、20年以上の経験があります。私はかつてサロゲートキーを持つoracleデータウェアハウスを作成したことがあり、データメンテナンスはまるで地獄のようでした。データに直接アクセスすることはできません。常にすべてのクエリを記述する必要があるため、代理キーを処理するのはひどいものになります。
SQLポリス

31

代理キーは変更する理由がありません。自然な鍵について同じことを言うことはできません。姓、メール、ISBN番号-それらはすべて1日で変更できます。


31

サロゲートキー(通常は整数)は、テーブルの関係を高速化し、ストレージと更新速度をより経済的にするという付加価値があります(ビジネスキーフィールドとは対照的に、サロゲートキーを使用する場合、外部キーを更新する必要はありません)。それは時々変わります)。

テーブルの主キーは、主に結合の目的で、行を一意に識別するために使用する必要があります。Personsテーブルを考えてください。名前は変更される可能性があり、一意であるとは限りません。

企業を考える:あなたはメルキアの他の企業とビジネスをしている幸せなマーキン企業です。会社名を主キーとして使用しない方が賢明なので、10文字の英数字全体でMerkiaの政府の一意の会社IDを使用します。その後、Merkiaは企業IDを変更することをお勧めします。それは大丈夫です、そもそもあなたが関与してはならない変更のために、dbエンジンのカスケード更新機能を使用します。その後、あなたのビジネスは拡大し、今ではフリードニアの会社と仕事をしています。Freedonianの会社IDは最大16文字です。会社IDの主キー(Orders、Issue、MoneyTransfersなどの外部キーフィールドも)を拡大し、主キー(外部キーも)にCountryフィールドを追加する必要があります。痛い!フリードニアでの内戦、それは 3つの国に分かれています。従業員の国名を新しい国名に変更する必要があります。レスキューへのカスケード更新。ところで、あなたの主キーは何ですか?(Country、CompanyID)または(CompanyID、Country)?後者は結合に役立ち、前者は別のインデックスを回避します(注文を国ごとにグループ化したい場合は、おそらく多くのインデックスも回避します)。

これらはすべて証明ではありませんが、結合操作を含むすべての用途で行を一意に識別する代理キーがビジネスキーよりも望ましいことを示しています。


あなたは最もクールに見えるユーザー名ですべてのインターネットに勝ちます!
Iainホルダー

1
それはほとんど反対意見です。「私はこれに同意しません。」
jcollum 2009

5
下矢印のツールチップには、「この答えは役に立ちません」ではなく、「これに同意しません」と表示されます。おそらくこの特定の答えでは意味が近いですが、それらは一般的に同じではありません。
tzot

1
誰かがあなたの答えが間違っていると思った場合、彼(/彼女)はまたそれが質問者を間違った方向(正しい方向の反対)に導くと考え、それゆえあなたの答えを「役に立たない」よりもさらに悪いと判断します、彼/彼女の心に反対票を正当化する。
Erwin Smout

1
うん、代理キーは病気です。1つは自然界に漏れて、それをpkeyとして使用するので、今度は独自の代理キーが必要です。次に、あなたの鍵が野生に(例えば、URLを介して)漏れ、病気が広がります。
Samuel Danielson

25

代理キーは一般的に嫌いです。高品質のナチュラルキーがない場合にのみ使用してください。考えてみると、テーブルに無意味なデータを追加することで状況が改善されると考えるのは不合理です。

ここに私の理由があります:

  1. 自然キーを使用する場合、テーブルは最も頻繁に検索される方法でクラスター化されるため、クエリが高速になります。

  2. 代理キーを使用する場合は、論理キー列に一意のインデックスを追加する必要があります。論理的な重複データを防ぐ必要があります。たとえば、pkがサロゲートID列であっても、組織テーブルで同じ名前の2つの組織を許可することはできません。

  3. 代理キーが主キーとして使用される場合、自然な主キーが何であるかははるかに明確ではありません。開発するとき、どの列のセットがテーブルを一意にするかを知りたいです。

  4. 1対多の関係チェーンで、論理キーチェーン。したがって、たとえば、組織には多くのアカウントがあり、アカウントには多くの請求書があります。したがって、Organizationの論理キーはOrgNameです。Accountsの論理キーはOrgName、AccountIDです。Invoiceの論理キーは、OrgName、AccountID、InvoiceNumberです。

    サロゲートキーが使用される場合、キーチェーンは、直接の親に対する外部キーのみを持つことで切り捨てられます。たとえば、InvoiceテーブルにはOrgName列がありません。AccountIDの列のみがあります。特定の組織の請求書を検索する場合は、組織、アカウント、および請求書テーブルに参加する必要があります。論理キーを使用する場合、組織テーブルを直接クエリできます。

  5. ルックアップテーブルのサロゲートキー値を格納すると、テーブルが無意味な整数で埋められます。データを表示するには、すべてのルックアップテーブルに結合する複雑なビューを作成する必要があります。ルックアップテーブルは、列の許容値のセットを保持するためのものです。代わりに整数の代理キーを格納することで体系化すべきではありません。正規化ルールには、値自体ではなくサロゲート整数を格納する必要があることを示唆するものはありません。

  6. 私は3つの異なるデータベースブックを持っています。それらのいずれも代理キーの使用を示していません。


7
必要な場合を除いて、代理キーは嫌いです。これらは、企業が多くのエラーの影響を受けやすい自然なキーを使用し、それらのエラーの影響を受けるデータベースを許容したくない場合に必要です。
Walter Mitty

26
-1:私は数十のアプリケーションを作成して保守しています。データ関連の問題が最も多かったのは、自然キーを使用している問題です。
ファルコン

6
いくつかのポイントは、代理キーがPKであるか、クラスター化された列である必要があると想定しています-真ではありません。ポイント1と5では、整数は4バイトであり、自然キーはほとんど常に多くのバイトであるという事実を無視しています。また、各非クラスター化インデックスは、クラスター化インデックスにある自然キーのバイトを繰り返す必要があるため、自然キーデータベースのテーブルとインデックスは、ページあたりの行数がはるかに少なくなり、読み取りパフォーマンスが大幅に低下します。 、クエリを遅くしますが、速くはしません。
ErikE 2013年

3
自然キー(例:原子番号、VINなど)に対するもう1つの理由は、ビジネスロジックが変化してデータの種類が増えることです。例-前:アトムの料金の追跡、後:アトムと化合物の料金の追跡。以前:積載量について自動車を追跡します。後:積載能力のために飛行機、ボート、バイク、人を追加します。
forforf 2013

3
主キーが部分的にも1)で構成されているテーブルがないか、1)変更可能で変更される属性)、または2)ユーザー入力(動的に生成されたルックアップリストなど)からのテーブルがないと思います。キーの不変性を保証できない場合は、コードまたは手動の「修正」スクリプトによって、これらすべてのエンティティの関係を更新する必要があります。あなたがそれをする必要がなかったなら...私はあなたのデータベースが代理キーなしで...そして異常であると思います。
code4life 2016年

18

私はこの無限の戦争についてのあなたと私の経験を共有したいと思います:自然対代理の主要なジレンマ。代理キー(人工的に自動生成されたもの)と自然キー(ドメインの意味を持つ列で構成されたもの)の両方に長所短所があると思います。したがって、状況によっては、どちらか一方の方法を選択する方が適切な場合があります。

多くの人々が代理キーをほぼ完璧な解決策として提示し、自然キーをペストとして提示するように思われるので、私は別の見方の議論に焦点を合わせます。

代理キーの短所

代理キーは次のとおりです。

  1. パフォーマンスの問題の原因:
    • それらは通常、自動インクリメントされた列を使用して実装されます。
      • 新しいIDを取得するたびにデータベースへのラウンドトリップ(これは、キャッシュまたは[seq] hiloのようなアルゴリズムを使用して改善できることは承知していますが、これらのメソッドにも独自の欠点があります)。
      • ある日、あるスキーマから別のスキーマにデータを移動する必要がある場合(少なくとも私の会社では非常に定期的に発生します)、IDの衝突の問題が発生する可能性があります。そしてはい、私はあなたがUUIDを使用できることを知っていますが、それらは最後の32桁の16進数が必要です!(データベースのサイズを気にする場合は、問題になる可能性があります)。
      • すべての代理キーに1つのシーケンスを使用している場合、確かに-データベースで競合が発生します。
  2. エラーを起こしやすい。シーケンスにはmax_valueの制限があるため、開発者は次の点に注意する必要があります。
    • シーケンスを循環させる必要があります(最大値に達すると、1,2、...に戻ります)。
    • データの順序付け(時間の経過)としてシーケンスを使用している場合、循環のケースを処理する必要があります(Id 1の列は、Id max-value-1の行よりも新しい場合があります)。
    • コード(および、内部IDであるために発生してはならないクライアントインターフェイス)が、シーケンス値を格納するために使用した32b / 64b整数をサポートしていることを確認してください。
  3. 重複しないデータを保証するものではありません。列の値はすべて同じであるが生成された値が異なる2つの行を常に持つことができます。私にとって、これはありますビューのデータベース設計の観点から代理キーの問題。
  4. ウィキペディアの詳細...

自然な鍵に関する神話

  1. 複合キーは、代理キーより非効率的です。番号!使用するデータベースエンジンによって異なります。
  2. 自然キーは実際には存在しません。申し訳ありませんが、存在します!たとえば、航空業界では、次のタプルは特定のスケジュールされたフライト(airline、departmentDate、flightNumber、operationalSuffix)に関して常に一意です。より一般的には、一連のビジネスデータが特定の基準で一意であることが保証されている場合、このデータセットは[良い]自然なキー候補です。
  3. 自然キーは子テーブルの「スキーマを汚染」します。私にとって、これは実際の問題というよりも感じです。それぞれが2バイトの4列の主キーを持つことは、11バイトの単一列よりも効率的かもしれません。さらに、4つの列を使用して、親テーブルに結合せずに(where句で4列を使用して)子テーブルを直接クエリできます。

結論

必要に応じて自然キーを使用し、適切な場合は代理キーを使用します。

これが誰かを助けたことを願っています!


3
予定されているフライトの出発日が変更されるとどうなりますか?すべての関連エンティティを追跡してキーを削除する必要がありますか、それとも実際に関連エンティティのすべてのキーを更新しますか?それとも、単純で特異なテーブル(おそらく3NFでもない)を扱っていますか?
code4life 2016年

エクセレントポイント@ code4life
forcewill 2016

@ code4life:ここで、operationalSuffixが飛び込みます。同じFlightNumberを維持してクライアントの混乱を避けるために、サフィックス(たとえば、「D」)だけを追加します。
mwnsiri

「列の値はすべて同じであるが生成された値が異なる2つの行を常に持つことができる」ので、列に一意制約または複合一意制約を設定するだけです。
wha7ever

15

常にビジネス上の意味がないキーを使用してください。それはただ良い習慣です。

編集:私はそれへのリンクをオンラインで見つけようとしましたが、できませんでした。ただし、「エンタープライズアーキテクチャのパターン」 [ファウラー]では、キー以外の意味を持たないキー以外の何も使用してはならない理由を説明しています。つまり、1つのジョブと1つのジョブのみが必要であるということです。


22
マーティン・ファウラーは多くのことをするかもしれませんが、彼はデータベース設計の権威ではありません。
Tony Andrews、

結論に達する前に、いくつかの理由付けを提供する必要があると思います。
Arne Evertsson、2011

4
@ArneEvertsoon理由はそこにあります。「つまり、1つのジョブと1つのジョブのみが必要であるということです。」単一の責任。
Iainホルダー2011

10

ORMツールを使用してデータクラスを処理/生成する場合は、代理キーが非常に便利です。より高度なマッパー(読み取り:hibernate)の一部で複合キーを使用できますが、コードが多少複雑になります。

(もちろん、データベースの純粋主義者たちは、代理キーの概念でさえ嫌いだと主張します。)

私は適切なときに代理キーにuidを使用するのが好きです。それらの主な利点は、事前にキーを知っていることです。たとえば、IDが既に設定され、一意であることが保証されているクラスのインスタンスを作成できますが、たとえば、整数キーでは、デフォルトで0または-に設定する必要があります。 1、保存/更新時に適切な値に更新します。

UIDは検索と結合の速度の点で不利ですが、それが望ましいかどうかは、問題のアプリケーションによって異なります。


6

サロゲートキーを使用する方が、変更される可能性がほとんどないため、私の意見ではより適切です。あなたが自然なキーとして使用する可能性があると私が考えることができるほとんどすべてが変わる可能性があります(免責事項:常に真であるとは限らないが、一般的に)。

一例として、車のDBがあります。一見すると、ナンバープレートをキーとして使用できると思うかもしれません。しかし、これらは変更される可能性があるため、悪い考えです。アプリのリリース、誰かがあなたのナンバープレートを光沢のある新しいパーソナライズされたものに変更できない理由を知りたくなったときに、それを実際に知りたいとは思わないでしょう。


1
残念ながら、車には変更されない自然なキーがあります。VIN(少なくともアメリカでは...)
jcollum 2009

@jcollumはい、それは公平な点です。私の意見はまだ残っていますが、私の例は必ずしもそうであるとは限りませんでした。
Mark Embling、

2
言語のリストは、ISOコードに基づいた自然キーの例です。したがって、特定の言語のテーブルからコンテンツをロードする場合はlanguages、言語コード(ID)がすでにテーブルにあるため、テーブルに参加する必要はありませんtexts
DanMan 2013年

@DanMan私はあなたに同意する必要があります。自然なキーでよりよく機能するいくつかの例が常にあります。ルールや一般的なアプローチは絶対的なものではありません。それは、私が100%あなたのアプローチを採用する1つの例です:-)
Mark Embling

5

可能な限り、常に単一列の代理キーを使用してください。これにより、レコードを維持するために1つの情報のみを追跡する必要があるため、結合、挿入、更新、削除がより明確になります。

次に、必要に応じて、ビジネスキーを一意の制約またはインデックスとしてスタックします。これにより、データの整合性が損なわれません。

ビジネスロジック/自然キーは変更できますが、テーブルの物理キーは決して変更しないでください。


4

データウェアハウスのシナリオでは、代理キーのパスに従うほうがよいと私は信じています。2つの理由:

  • ソースシステムから独立しているため、データタイプの変更などの変更による影響はありません。
  • サロゲートキーには整数データ型のみを使用するため、DWに必要な物理スペースは少なくなります。また、インデックスはより適切に機能します。

2

代理キーは、ビジネス情報が変更または同一になる可能性がある場合に役立ちます。結局のところ、ビジネス名は国全体で一意である必要はありません。たとえば、カンザス州とミシガン州にあるスミスエレクトロニクスという2つの企業を扱っているとします。住所で区別できますが、状況は変わります。状態さえ変化することができます。カンザス州カンザスシティのスミスエレクトロニクスが川を越えてミズーリ州カンザスシティに移動した場合はどうなりますか?これらのビジネスを自然なキー情報で明確に区別する明確な方法はないため、代理キーは非常に役立ちます。

ISBN番号のような代理キーと考えてください。通常、本はタイトルと著者で識別します。しかし、HPウィルモットによる「パールハーバー」というタイトルの本が2冊あり、それらは異なるエディションだけでなく、明らかに異なるブックです。そのような場合、私は本の外見を参照することもできますし、以前のものと後のものを参照することもできますが、ISBNに頼るのも同様です。


1
私はここであなたの例に同意しなければならないと思います。ISBN番号は本の属性です。代理キーは残りの行データから独立しているため、ISBNがすでにすべての本を一意に識別している場合でも、この位置は本のテーブルに別の代理キーを使用することを推奨します。
Christopher Cashell

または、ISBNを代理キー自体と見なします。これは意味のない識別子であり、特定の本に適用されるコードにすぎません。本の表を作成している場合、ISBNが主キーになることもあります(行ごとに1つの本があると仮定します)。
David Thornley、2010年

@Christopher Cashell-1年前からこの投稿に出くわしましたが、何か追加したいと思いました。ISBNは一意であることが保証されておらず、重複している場合があります。私は何年も図書館で働いていた友人がいて、ISBNが重複している本に出くわすことがよくあります。問題は、ISBNの一意性が、すべての出版物のすべての番号を確実にする1つの機関ではなく出版社にあるということです。ユニークであり、それらの出版社は常に一緒に行動していませんでした。
トーマス

2
1年前からこの投稿に出くわし、ISBNが実際に自然なキーであることを述べたいと思いました。代理キーとは異なり、キー値自体に焼き付けられる意味があります。たとえば、キーの一部は発行者を識別します。また、前述のとおり、それらが一意であるとは限りません。彼らはユニークであることになっていますが、そのユニークさは出版社に由来し、常に完璧であるとは限りませんでした。
トーマス

技術的には、企業は州間を移動できません。何が起こるかというと、新しい会社が新しい状態で作成され、資産が移転されます。これはデータベース情報でも機能します。
ウォーレンデュー2014年

2

SQL Serverはこれらのデータを物理的に並べ替えることができないため、ランダムな代理キー、つまりXY8D7-DFD8Sを読み取るGUIDにクラスター化インデックスを配置することはお勧めできません。代わりに、これらのデータに一意のインデックスを配置する必要がありますが、メインテーブル操作に対してSQLプロファイラーを実行し、それらのデータをデータベースエンジンチューニングアドバイザーに配置することも有益な場合があります。

スレッド@ http://social.msdn.microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129beを参照してください


SQL Server GUID ソートできると確信しています。
マイケルグリーン

これは正確ではありませんが、GUIDを評価できますが、結果として得られるソートは人間にとって無意味ではありません。stackoverflow.com/questions/7810602/…–
ブライアンスワン

1
正しい説明ですが、「SQL Serverにはこれらを物理的に並べ替える機能はありません」とはかなり異なります。
Michael Green、

2

ケース1:テーブルが50未満のタイプ(挿入)のルックアップテーブルである

ビジネスキーまたは自然キーを使用します。例えば:

Table: JOB with 50 inserts
CODE (primary key)       NAME               DESCRIPTION
PRG                      PROGRAMMER         A programmer is writing code
MNG                      MANAGER            A manager is doing whatever
CLN                      CLEANER            A cleaner cleans
...............
joined with
Table: PEOPLE with 100000 inserts

foreign key JOBCODE in table PEOPLE
looks at
primary key CODE in table JOB

ケース2:テーブルは何千もの挿入があるテーブルです

代理/自動インクリメントキーを使用します。例えば:

Table: ASSIGNMENT with 1000000 inserts
joined with
Table: PEOPLE with 100000 inserts

foreign key PEOPLEID in table ASSIGNMENT
looks at
primary key ID in table PEOPLE (autoincrement)

最初のケースでは:

  • テーブルJOBとの結合を使用せずに、「SELECT * FROM PEOPLE WHERE JOBCODE = 'PRG'」を使用するだけで、テーブルPEOPLEのすべてのプログラマーを選択できます。

2番目の場合:

  • 主キーが整数であるため、データベースクエリが高速になります。
  • データベース自体が次の自動インクリメントを提供するため、次の一意のキーを見つけることに煩わされる必要はありません。

2

これは、代理キーがほとんど常に意味を持つケースの1つです。データベースに最適なものまたはオブジェクトモデルに最適なものを選択する場合がありますが、どちらの場合も、意味のないキーまたはGUIDを使用する方が適切です。これにより、インデックス作成がより簡単かつ高速になり、変更されないオブジェクトのIDになります。


1

コース用の馬。私の偏見を述べるために; 私は最初に開発者なので、主にユーザーに実用的なアプリケーションを提供することに関心があります。

私は自然キーを使用するシステムで作業しており、値の変更が波及することを確認するために多くの時間を費やす必要がありました。

私は代理キーのみのシステムで作業してきましたが、唯一の欠点は、パーティション化のための非正規化されたデータがないことです。

ジョインごとのテーブル数が多いため、私が一緒に働いてきたほとんどの従来のPL / SQL開発者は代理キーを好みませんでしたが、テストデータベースと本番データベースでは汗を流しませんでした。追加の結合はアプリケーションのパフォーマンスに影響を与えませんでした。「Xa = YbのX内部結合Y」のような句をサポートしないデータベースの方言、またはその構文を使用しない開発者では、代理キーの追加の結合により、クエリが読みにくくなり、入力や入力が長くなります。チェック:@Tony Andrewsの投稿を参照してください。しかし、ORMまたはその他のSQL生成フレームワークを使用している場合は、それに気付かないでしょう。タッチタイピングも軽減されます。


また; サロゲートキーがまさにそれであるということを本当に理解したい場合は、ランダムな大きな数から開始し、シーケンスを1ではなく3+ずつインクリメントするか、同じシーケンスを使用して複数のキーの値を生成します。
WillC、2012

1

たぶんこのトピックに完全に関連しているわけではありませんが、代理キーを扱っている頭痛の種です。Oracleの事前提供分析では、ウェアハウス内のすべてのディメンションテーブルに自動生成されたSKが作成され、それらもファクトに保存されます。したがって、新しい列が追加されたり、ディメンション内のすべてのアイテムにデータが入力されたりするときに、それら(ディメンション)を再読み込みする必要がある場合は常に、更新中に割り当てられたSKが、SKをファクトに保存されている元の値と同期させないようにします。それに結合するすべてのファクトテーブルの完全なリロード。たとえSKが無意味な数であったとしても、元のレコードと古いレコードでは変更できない方法がいくつかあると思います。多くの人が知っているように、すぐに使用できるものが組織のニーズに対応することはめったになく、常にカスタマイズする必要があります。これで、倉庫に3年分のデータが保存されました。Oracle Financialシステムからの完全なリロードは非常に大きいです。したがって、私の場合、これらはデータ入力から生成されるのではなく、パフォーマンスのレポートに役立つようにウェアハウスに追加されます。私はそれを理解しましたが、私たちの状況は変わります。そしてそれは悪夢です。


0

ポイントインタイムデータベースの場合、代理キーと自然キーの組み合わせが最適です。たとえば、クラブの会員情報を追跡する必要があります。メンバーの一部の属性は変更されません。例:生年月日。ただし、名前は変更できます。したがって、member_idサロゲートキーを使用してMemberテーブルを作成し、DOBの列を作成します。person nameという別のテーブルを作成し、member_id、member_fname、member_lname、date_updatedの列を作成します。このテーブルでは、自然キーはmember_id + date_updatedになります。

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