最初の図は、Has-a 関係を示しています。パーツには他のパーツが含まれます。エンジンは多くの部品で構成されており、その中にはガスケットもあります。
2 番目の図は Is-a 関係を示しています。部品はエンジンである場合もあれば、ガスケットである場合もあれば、その他の多くのものである場合もあります。
抽象的な ER モデリングの世界では、Is-a 関係は Generalization-Specialization の名前で呼ばれます。私が「抽象的 ER モデリング」と言っているのは、多くの ER 図が実際にリレーショナル モデルを表しているためです。
興味深いことが始まるのは、ER モデルからリレーショナル モデルに切り替えるときです。
Has-a 関係は、リレーショナル用語で簡単にモデル化できます。これは実質的にリレーショナル モデリング 101 です。一方の主キーを参照する外部キーを多側に配置すれば完了です。
Is-a 関係は、リレーショナル用語でモデル化するのはそれほど簡単ではありません。オブジェクト モデリングでは、これは実質的にオブジェクト モデリングの 101 であることがわかります。クラスとサブクラス (タイプおよびサブタイプと呼ばれることもあります) を使用するだけで、オブジェクト モデリングの継承機能が面倒な作業をすべて行います。
リレーショナル モデリングでは、物事はそれほど簡単ではありません。このケースに対処するためのよく知られた手法がありますが、これらの手法はリレーショナル モデリングのチュートリアルでは省略されることがよくあります。これらの手法の 1 つの詳細については、次のタグの下にあるタグ wiki を参照してください: class-table-inheritance。
この分野では ORM ツールが優れていると思われるかもしれませんが、そうではないようです。
編集: もう一度強調する 1 つのポイント: ER モデリングとテーブル設計は同じアクティビティではありません。主題を構成するエンティティや関係を設計することはありません。主題を研究することによって、またはおそらく主題の専門家にインタビューすることによって、実体と関係を発見します。次に、以前に発見されたエンティティーと関係を説明するすべてのデータ値の便利なコンテナーとして機能するテーブルを設計します。
実際には、これは反復的なプロセスになる可能性があります。
次に、2 番目のダイアグラムをカバーする 2 つの可能なテーブル デザインに目を向けましょう。
最初のデザインは 4 テーブル デザインです。Part、Motor、Gasket、Motor_Gasket の 4 つのテーブルがあります。4 つの主キーは、PartID、MotorID、GasketID、および (MotorID、GasketID) 複合主キーになります。
MotorID は自動採番では設定されません。代わりに、アプリケーションは、新しいモーターが含まれているときに生成されたばかりの PartID のコピーを提供します。次に、MotorID は 2 つの役割を果たします。それは、独自のテーブルで PK として機能し、PartID を参照する FK としても機能します。
GasketID も同様の扱いを受けます。モーターとガスケットに共通の属性は、Part テーブルの列に表示されます。その他の属性は、必要に応じて Motor テーブルまたは Gasket テーブルに入ります。
Motor_Gasket テーブルには、MotorId と GasketID の 2 つの列があります。これらは、適切なテーブルを参照する FK です。このテーブルの PK は行全体です。
Motor_Gasket テーブルは、Contains リレーションシップを実装します。PartID と MotorID または GasketID の間の値の「継承」は、「IS-A」関係を実装します。
もう1つのデザインは2テーブルのデザインです。
Part と Motor_Gasket の 2 つのテーブルがあります。
すべてのモーターとすべてのガスケットがパーツ テーブルの行を占めます。パーツのタイプを指定する PartType という列があります。モーターまたはガスケットを説明するすべての属性は、Part テーブルにあります。適用できないスペースは NULL に設定されます。
Motor_Gasket テーブルには、以前とまったく同じように 2 つの列がありますが、両方の列が Part テーブルの参照 (異なる行) を参照しています。
この 2 つのデザインのうち、どちらが優れていますか? 場合によります。