複合キーの外部キーとしての代理キー
-
06-07-2019 - |
質問
同様の質問があるかもしれませんが、ガイダンスに十分近い質問は見つかりませんでした。
この仕様を与えてください
Site
---------------------------
SiteID int identity
Name varchar(50)
Series
---------------------
SiteID int
SeriesCode varchar(6)
...
--SeriesCode will be unique for every unique SiteID
Episode
----------------------
SiteID int
SeriesCode varchar(6)
EpisodeCode varchar(10)
...
提案された設計/実装は
Site
----------------------------
SiteID int identity
Name varchar(50)
Series
-------------------------------------------
SeriesID int identity, surrogate key
SiteID int natural key
SeriesCode varchar(6) natural key
UNIQUE(SiteID, SeriesCode)
...
Episode
-------------------------------------------
EpisodeID int identity, surrogate key
SeriesID int foreign key
EpisodeCode varchar(6) natural key
...
これに何か問題がありますか?ここで、SeriesIDサロゲートを外部*キーとして使用しても大丈夫ですか?発生する可能性のある明らかな問題を見逃しているかどうかはわかりません。または、複合自然キー(SiteID + SeriesCode / SiteID + EpisodeCode)を使用する方が良いでしょうか?本質的には、エピソードテーブルとシリーズテーブルを分離しますが、それは私には適していません。
追加する価値があるのは、これらのテーブルに入力される未加工の入力データで、SeriesCodeが「ABCD-1」のように見え、EpisodeCodeが「ABCD-1NMO9」のように見えることです。
*:" virtual"外部キー。以前は上位により決定されていたため、実際の外部キー
は使用しないでください。解決
はい、すべて正常に見えます。私ができる唯一の(マイナーな)ポイントは、エピソードから4番目の子テーブルがハングアップしない限り、おそらくEpisodeIdは必要ないということです。Episode.EpisodeCodeは、エピソード内の行を識別および検索するのに十分な単一の属性自然キーです。もちろん、そのままにしておいても問題はありませんが、一般的なルールとして、子テーブルのFKのターゲットとして機能する代理キーを追加し、冗長データ行を識別して制御するためにすべてのテーブルに自然キーを追加しようとします...そのため、テーブルに、それを参照するFKを持つ他のテーブルがない場合(そうすることはありません)、私は時々その中に代理キーを含めることを気にしません。
他のヒント
「仮想」とは外部キー?上層部は外部キー制約を使用しないことに決めましたか?その場合、外部キーをまったく使用していません。ふりをしているだけです。
そして、エピソードはエンティティにとって最良の選択ですか?それは本当にショーやポッドキャストなどを意味するのではなく、たまたま今シリーズの一部になっているだけです。もしそうなら、それは将来変わるでしょうか?最終的にエピソードは、シリーズ外のショーを含むように乱用されますか?その場合、シリーズを介してエピソードをサイトに結び付けると戻ってくる可能性があります。
それをすべて考えて、あなたがうなり声としてあなたはおそらくそれのどれも変えることができないと仮定します:もし私があなたなら、私は可能な限り自然なキーを使ってより安全に感じるでしょう。外部キーの制約がない場合、不良データの認識が容易になります。また、後からSeriesCode = 'EMPTY'トリックに頼る必要がある場合は、自然キーでも簡単になります。
私の提案:
次の3つの状況を除き、自然/ビジネスを可能な限り主キーとして使用します:
- 自然/ビジネスキーは、挿入時の不明です
- 自然/ビジネスキーは良くない(一意ではなく、頻繁に変更される可能性があります)
- ナチュラル/ビジネスキーは 3列以上の複合であり、テーブルには子テーブルがあります
状況1および2では、代理キーが必要です。
状況3では、代理キーが強く推奨されます。