デバイスというテーブルがあります。このテーブルに格納されるほとんどのデバイスは、シリアル番号と部品番号によって一意に識別できます。ただし、シリアル番号と部品番号が割り当てられていないデバイスタイプもあります。代わりに、それらは別のフィールド(内部ID)によって一意に識別できます。
このテーブルの代理キーを作成する必要がありますか、それとも複合主キー(シリアル番号、パーツ番号、内部ID)を作成し、シリアル番号とパーツ番号の列が提供されていない場合は、それらにデフォルト値を挿入する必要がありますか?現在、部品番号とシリアル番号がないデバイスタイプには、今後のリリースで番号が割り当てられます(5年後になる可能性があります)。このシナリオでは、代理キーまたは複合キーを作成する必要がありますか?または、3つの一意の属性を使用して、プログラムでハッシュを作成し、それをテーブルの代理キーとして使用する必要がありますか?
現時点では、代理キーを主キーとして使用します。自然キーが利用できるようになったら、それらをnullにできない一意の制約にします。
[〜#〜] yagni [〜#〜] の原則により、「実際の」現在の要件-が可能な主キー(または5月に到着しない場合があります)を検討する価値はありません今!
代理キーは非常に実際に広く使用されており、純粋主義者の恐怖に大いに役立ちます。 このスタックオーバーフローの回答 (およびスレッドの残りの部分)を参照してください。
代替キーではなく主キーについて話していることを明確にすることから始めるべきだと思いますよね。また、主キーについて説明しているため、時間の経過とともに変化しないことが最善です。また、特にこのPKを指すFKがある場合は、可能な限り小さくすることをお勧めします。
自然キーを回避する主な理由(まだすべてのケースでキーが存在するわけではないこと、および5年はlong特に発生しない可能性がある場合に待機する時間です)は、信頼性の要因です。あなたはデータの出所を信頼していますか?機械によって生成されたか、人が入力したものですか?データを入力する人間は、間違いをする可能性があり、間違いを犯すことがよくあります。また、データがマシンで生成された場合でも、インポートプロセスのバグが何らかの方法で値を壊す可能性があります。このため、私は代理キーを好む傾向があります。確かに、代理値が「無意味」であると文句を言う人もいますが、紙や画面で論理データモデルを見ることについて話しているのではありません。信頼性が高く効率的な値は、常に「有意義」を勝ち取ります。大文字と小文字を区別しない照合と(JOINの場合でも)比較される可能性が最も高いいくつかのテーブルにコピーされた(さらにいくつかのインデックスにコピーされた)30バイト(または何でも)のキーは、4バイトのINTを選択できる場合、意味がありません。単純なバイナリ比較。
「自然な」キー列にはインデックスが付けられ、代替キーになります。これは、後続のすべてのJOINとクエリで使用される代理キーを取得するためにアプリがレコードを検索するために使用するものです。この列は、データタイプ、長さ、値など、ビジネスリクエストと同様に、時間の経過とともに変化する可能性があります。リクエストされた変更にはさらに1〜6か月かかることを通知する必要はありません(サイズに応じて)システムと変更の範囲)これは、非常に多くのテーブルに影響を与えるためです。つまり、計画により多くの時間、変更を開発するためにより多くの時間、テストに必要な時間、および何かがテストに巻き込まれずに引き起こされるリスクが高くなります1顧客を混乱させ、サポートスタッフの負担になるサポートリクエストをログに記録する以上の顧客。
複合キーは、本質的に間違っているわけではありませんが、ここでは何も追加しないようです。そして実際には、それらを持っているデバイスタイプの既存のシリアル番号の一意性に対抗するように思えます。
また、「プログラムでハッシュを作成し、それを代理キーとして使用するための3つの固有の属性」を使用することもお勧めしません。繰り返しますが、これは、これら3つの「一意の属性」のいずれかが変更された場合に変更できる値のようです。また、GUIDがPKに最適であると考え始めた人と同じボートにあなたを残すハッシュの非順次的な性質は言うまでもなく、PKとしての使用に理想的なサイズよりも大きくなります;-).