これは簡単な質問ではありません... SQL データベースは、クラス階層のモデリングが得意ではありません。
優れた ORM が必要です。
クラス階層をテーブルに入れると、次のようになります。
まず、適切であることを確認します。たとえば、Web CMS のノード、記事などを同じテーブルに配置することは理にかなっています。これらはすべて同じものの変形であるためです。
検索、インデックス作成、および SQL クエリの作成のためにデータベース列を作成する必要がありますが、すべての情報をデータベース列に格納する必要はありません。残りは BLOB 列のシリアル化されたオブジェクトに格納できます。
この表には、もちろん、この行がどのクラスのインスタンスであるかを示す列があります。すべてのクラスに共通するいくつかの「コア」列、基本的には基底クラスのフィールドがあります。- 一部のサブクラスでのみ使用されるが、検索する必要があるため、インデックスを作成する必要があるその他の列 - オブジェクトの他のすべてのデータを含む BLOB。
基本的に、オブジェクトをデータベースに保存すると、そのクラスに応じて関連する列が埋められ、残りのデータ (またはオブジェクト全体) が BLOB に押し込まれます。
これの優れた点は、検索やインデックス作成の必要がなく、格納されるだけのメンバー値を追加した場合、それをデータベース列に入れる必要がないため、データベースにまったく変更を加えないことです。 : シリアル化された BLOB に格納されます。唯一できることは、デシリアライゼーション コードにこのメンバーのデフォルト値を追加することです。そのため、既にデータベースにあり、このメンバーを持たないこのクラスのオブジェクトには、適切なデフォルト値が設定されます。
必要に応じて、オブジェクト形式をバージョン化することもできます。これはより複雑になります。
ただし、このスキームにはいくつかの欠点があります。
制約の適用が難しい : - 列を持つフィールドにのみ制約を適用できます。- 一部の列は一部のクラスでのみ発生するため、データベースはクラス階層について少し知る必要があります。
たとえば、住所を別のテーブルに配置し、関連するフィールド (郵便番号、国、通り、番号など) を追加したい場合があります。これらすべてをメイン テーブルに配置すると、列が増えすぎます。また、ある時点で、別のテーブルにあり、住所も持っているいくつかの顧客またはその他のものを追加したい場合があるため、別のテーブルに住所を入れてそれらを参照することをお勧めします。
人や企業なども同様です。
ショップには住所がありますが、カートにはありません。そのため、データベース DDL で、タイプが「ショップ」でタイプが「カート」ではない場合、テーブルの行が住所を参照する必要があることを表現する必要があります。
少し毛むくじゃらになることがあります。
また、たとえば、10 のショップと 100.000 のカートがある場合、パフォーマンスのために、テーブルを分割することは興味深いかもしれません。
今他の解決策があります:
たとえば、すべてのコードと基本メンバーを基本クラスに配置し、tableName を派生クラスで変更されるクラス属性にすることができます。このように、テーブル名を変更するだけで、すべてのコードが別のテーブルに適用されますが、書き直す必要はありません。
次に、クラスごとに 1 つのテーブルを取得します。
もちろん、クラス階層がより複雑になった場合は、上記の方法を各テーブルに適用できます。
2つの間で選択する方法?
基本的にWeb CMSを作ってテーブルに格納する場合、Nodeから派生したクラスのオブジェクトは以下のようになります: - アーティクル - 凡例付き画像 - ギャラリー - など
これらのオブジェクトはすべて基本的に同じものです。それらはすべて Title、TextContent フィールドを持ち、ParentNode に属します。
TextContent で「foo」のキーワード検索を行う場合、すべてのオブジェクトが同じテーブルにあると、はるかに簡単になります。
ParentNode のすべての子を一覧表示して Web ページに表示したい場合、すべてが 1 つのテーブルにある方がはるかに簡単です。
したがって、この場合、最初の方法は本当に利点があります。
あなたの場合、オブジェクトはそれほど似ていません。
個人的には、彼らに同じ基本クラスを与えることさえしません。「ThingWithCoordinates」という名前の Mixin を作成し (おそらくもっと短いもの)、これをクラスに追加します。
さて、ベーカリーはショップから継承できるほど近くにあるかもしれませんが、カートとラックはおそらくそうではありません。
あなたの場合、私は間違いなくいくつかのテーブルを使用します。また、各テーブルに複数のクラスを格納する必要がある場合は、最初の方法を使用します。
最も重要なことは、クラス階層 (およびテーブル) は関連するもの (カー ディーラーやベーカリーはショップ) に基づいている必要があり、実際には他に共通点がないオブジェクト (カートとショップなど) の間に存在する共通の機能ではないということです。このために、共通コードを共有する mixin がありますが、基本クラスはありません。