私はデータモデリングプロジェクトに取り組んでおり、4つの列しかないhistory
テーブルに最適なデータモデリングアプローチを見つけようとしています。
CREATE TABLE FooHistory
(
SecurityID INT (FK), -- Part of the natural PK.
FieldID INT (FK), -- Part of the natural PK.
DateCreated DATETIME2(0), -- Part of the natural PK.
Value VARCHAR(50)
);
このテーブルのnatural複合キーは(DateCreated, SecurityId, FieldID)
であり、ETLプロセスは30分ごとにこのテーブルに〜2K行を追加します。
質問
複合PRIMARY KEY(PK)(DateCreated, SecurityId, FieldID)
を宣言する場合と、新しいIDENTITY列(つまり、システム生成サロゲート)を追加してPKとして使用する場合の長所と短所?
IDENTITY列を追加してそれをPKとして使用すると、非PK列の間に機能的な依存関係があるため、このテーブルは第3正規形(3NF)にならない、つまり(DateCreated, SecurityId, FieldID)
およびValue
。
このテーブルには履歴データが保持されるため、このテーブルを他の外部テーブルに結合することは想定していません。アプリケーションは主にSELECTステートメントを使用してテーブルと対話します。これらの仮定に基づいて、テーブルを3NFに維持し、複合PKを宣言することは価値がありますか、またはこのテーブルにIDENTITY列を追加する必要がありますか?
検討中のケースの説明によると、(a)IDENTITY
プロパティを介してHistory
テーブルに(a)システム割り当てサロゲート*(サロゲート簡潔にするため)を保持する列を追加すると、(b)不要になります。
サロゲートを保持する列は、一時的なnaturalPRIMARY KEY(PK)制約がFOREIGN KEY(FK)制約定義から参照される可能性がある場合に役立ちます。しかし、そのような暫定的なPK制約は
その結果、(1)が単一列を指すFK制約があると、somewhatは、次のような自然なKEYの「代替」として機能します。上記および(2)は軽量の値を維持するため、評価する価値があります。手元にあるHistory
テーブルについては、論理的に広くなく、重い物理的な足場によってサポートされていません。
さらに、サロゲートの列をアタッチすると、一時的に不要な要素(およびおそらく、推測に対応する物理INDEXの要素)が組み込まれるため、問題のテーブルが必然的に広くなるため、動作が遅くなる可能性があります。したがって、データベースの全体的なパフォーマンスへの影響を考慮すると、実際的な値は提供されない場合があります。
この特有の列のクラスが役立つ場合がある状況は、独立したエンティティタイプを表すテーブルに固執する場合です。† しかし、ご存知のように、上記のような状況でも、特定の各テーブルは、(i)個別分析と(ii)そのような列の貼り付けが便利かどうかを判断するためのコンテキスト分析を要求します(そして、あなたが質問をしたのはそのためだと思います) )。
もちろん、論理レベルでは、サロゲートを維持する列は、ビジネスドメインの意味(結果セットの可読性と解釈を妨げる)をより多くキャプチャすることも、保護することもありませんreal行の一意性(無意味な値を保持する列は、追加の非データアーティファクトであるため、本物データ要素)。これらの側面の証拠については、 thisoutstandingStack Overflow answer by @PerformanceDBA を参照してください。
ただし、これをHistory
テーブルに「追加」し、それをPKとして「使用」し、同時に列の組み合わせを宣言する(DateCreated, SecurityId, FieldId)
代替キーとして‡ (AK)(a)複合UNIQUE制約の構成、および(b)上記の組み合わせのすべての列をNULL不可として指定(実際にになる配置trueデータ要素に関して行の一意性を保証します。このように、Value
という名前の非キー列は、機能的に両方に依存します。
したがって、テーブルは3NFに準拠します§ とにかく、サロゲートを備えたカラムの使用はメリットを提供しませんが、それは過度です。
それが過度になる理由の実際的な例は次のとおりです。
History
テーブルは、WHERE句の条件として自然AKの一部である1つ以上の列を含むSELECTステートメントによってほとんどの場合クエリされます(サロゲートを囲む列は、終了する意味があるため、ほとんど含まれません)ユーザー)。物理レベルで、複合PK定義を提供するための適切なINDEXing戦略を確立することは、関連するプロセスの機能を最適化するために最も重要であることに注意することが重要です。該当するINDEX構成によって支援された列の適切な順序の。
文末脚注
* システムによって割り当てられたサロゲートは、リレーショナルパラダイムの作成者である Dr. Edgar Frank Codd が執筆した データベースリレーショナルモデルを拡張してより意味のあるものにする というタイトルの1979年の論文で評価されました。上記の論文では、ほとんどのデータベースでルールが守られていないことを確認したにもかかわらず、データベースユーザーにサロゲート値を表示しないように規定されています。現在の回答は、審議中のシナリオでは、サロゲートが通常のビジネスコンテキスト値と同じように公開されるという仮定に基づいています。
†概念レベルでは、エンティティタイプ(またはエンティティプロトタイプ)は独立であり、そのすべてのオカレンス(つまり、行、 SQLテーブルに保持されている場合)は、それ自体の属性(つまり、列)の1つ以上の値によって一意に識別されます。 依存1つは、他のエンティティタイプに属する1つ(または複数)の属性の値を使用して、そのインスタンスを一意に識別できるようにする必要があるものです。
‡ ALTERNATE KEYは、関連するテーブルの各行を一意に識別する値を保持する列(または列の組み合わせ)ですが、PRIMARY KEYとして選択されていません。各テーブルは、ゼロ、1つ、または複数のALTERNATE KEYSを持つことができます。
§ これがそうである理由を分析するには、 大規模共有データバンクのデータのリレーショナルモデル (1970)およびその後の正規形および正規化の真の定義を参照してください。 データベースリレーショナルモデルのさらなる正規化(1971)の(Joel Brownの次の回答で提案されている)正規形は、両方ともEF Codd博士によって「自然に」機能します。元のリレーショナルモデル(1970)にはサロゲートが含まれていないことに言及する価値があります。
また、代理キー(IDENTITY)を追加する必要があるか、良いか、役立つかという問題に対処した人もいます。 代理キーを追加すると3NFに違反するかどうかについての質問に対処します。
E.F. Coddによって提示された第3正規形の正式な定義では、次の場合に限り、関係は3NFであると述べています。
(強調は私のものです)
テーブルは複数の候補キー(MDCCLの用語では代替キー)を持つことができます。代理キーを追加しても、自然キー列が非キーステータスに降格されません。したがって、サロゲートキーを追加した場合でも、Value
列は完全に機能的に依存している各候補キーの列の。
このテーブル(履歴として)が主にINSERT操作用であり、DateCreatedも単調増加であると想定している場合(PKの選択に関する重要な考慮事項の1つは、PKによってページ分割が発生しないことです)、必要ありません。 PKのためだけに整数列を追加するには、コンポジットPKを使用してもまったく問題ありません。