web-dev-qa-db-ja.com

拡張エンティティ関係図:サブクラスに外部キーまたは主キーがありますか?

次の例を考えてみてください(ちなみに、これらはばらばらです)。

enter image description here

私が推測している2つのシナリオがあります。

  1. リレーショナルテーブルに変換する際、PROGRAMMERの行は一意であり、EMPLOYEEテーブルには存在せず、PRIMARY KEYがあります。

  2. それらはすでにEMPLOYEEテーブルに存在し、PROGRAMMERはそれを参照する外部キーを持っています。

どちらのシナリオが正しいですか?または両方が間違っていますか?

1
MrRobot9

それは/または状況ではありません。特定のシステムに対する答えは、これら2つのオプションの組み合わせとして存在する場合があります。説明させてください。

Programmer、Engineer、およびAdminテーブル間で共通する唯一の属性がEmp#である場合、それらを個別のテーブルとして実装する可能性があります。それぞれが主キーとしてEmp#を持ちます。ランタイムシステムに追加の値が追加されていないため、Employeeテーブルはまったく実装しません。

3つのサブタイプに共通の列が多数ある場合(たとえば、Name、HireDate、Department .. HolidayBalance、ContactNumberなど)、サブタイプ固有の値がほんの少し(図に注釈を付けたように)、すべての列を配置できます従業員で、不適切なもの(たとえば、プログラマのEType)をNULLにします。 NULLを除外するのが面倒になる場合は、サブタイプごとにビューを定義できます。

おそらく真実はこれら2つの中間にあります。各サブタイプには、独自のテーブルを保証するのに十分な特定の属性がありますが、従業員テーブルを正当化するのに十分な共通の属性もあります。この場合、Emp#をEmployeeの主キーにし、各サブタイプにもEmp#の主キーを割り当てます。さらに、Programmer.Emp#を、Employee.Emp#を参照する外部キーとして定義します。他のサブタイプについても同様です。このようにして、各サブタイプ内で一意性が維持され、サブタイプとスーパータイプの間の整合性も維持されます。つまり、従業員と各サブタイプの間に1対1の関係を作成します。

Emp#でまだ達成できないことは何も追加されていないため、各サブタイプ(たとえばProgrammerId)に代理キーを実装しません。

サブタイプ間の相互排除を宣言的に保証することは難しいことに注意してください。これは、アプリケーションまたはトリガーを介して適用されます。

2
Michael Green