継承をサポートしていないリレーショナルデータベースに継承されたクラスを永続化する必要がある場合のヒント/テクニックは何ですか?
この古典的な例があるとしましょう:
Person -> Employee -> Manager
-> Team lead
-> Developer
-> Customer -> PrivilegedCustomer
-> EnterpriseCustomer
データベースを設計するために利用できる手法は何ですか?それぞれの長所と短所?
p.s.データベースの継承に関するいくつかの質問を検索して見つけましたが、ほとんどはそれをネイティブにサポートするデータベースエンジンへの変更に関するものでした。しかし、SQL Server 2005で立ち往生しているとしましょう...私のオプションは何ですか?
3つの一般的な戦略:
各クラスに定義されたプロパティと、最上位のスーパークラステーブルに戻る外部キーを含む、階層内の各クラスのテーブルを作成します。したがって、vehicle
テーブルとcar
やairplane
のようなvehicle_id
列を持つ他のテーブルがある場合があります。ここでの欠点は、1つのクラスタイプを取得するためだけに多くの結合を実行する必要がある場合があることです。
すべてのプロパティを含む階層内のクラスごとにテーブルを作成します。シーケンスのようなものを使用しない限り、すべてのテーブルで共通のIDを維持するのは簡単ではないため、これは注意が必要です。スーパークラスタイプのクエリでは、問題のすべてのテーブルに対してユニオンが必要になります。
クラス階層全体に対して1つのテーブルを作成します。これにより、結合と結合が排除されますが、すべてのクラスプロパティのすべての列が1つのテーブルにある必要があります。一部の列は異なるタイプのレコードに適用されないため、ほとんどの列をnull許容のままにしておく必要があります。たとえば、vehicle
テーブルには、wingspan
タイプに対応するAirplane
という列が含まれている場合があります。この列をNOTNULLにすると、テーブルに挿入されたCar
のインスタンスには、wingspan
の値の方が理にかなっている場合でも、NULL
の値が必要になります。列をNULL可能のままにすると、チェック制約を使用してこれを回避できる可能性がありますが、醜くなる可能性があります。 ( 単一テーブル継承 )
特定の状況ではデータベースの継承に注意してください。監査戦略のアプリケーションにデータベースを実装した結果、パフォーマンスのボトルネック/悪夢が発生しました。
問題は、使用したベーステーブルが挿入のみであり、急速に変化するため、最終的にデッドロックが発生したことでしたallその場所で。現在、これらを独自のテーブルに分割することを計画しています。これは、パフォーマンスの悪夢に対して15の異なるテーブルに同じ列を配置するという頭痛の種は、それだけの価値があるためです。これは、エンティティフレームワークが必ずしも継承を効率的に処理するとは限らないという事実によっても悪化しました(これはMicrosoftによる既知の問題です)。
とにかく、私たちはこの問題について絞り込みを行ってきたので、私がいくつかの知識を共有したいと思っただけです。
第8章次のリンクの継承マッピングでもこれについて説明しました。 http://nhibernate.info/doc/nh/en/index.html#inheritance
NHibernateドキュメントです。