相互に排他的な1対1の関係をいくつか持つことは悪い習慣ですか?


38

セイ、テーブルには、carテーブルに1対1の関係を有するelectric_cargas_carhybrid_car。場合carelectric_car、それはもはやに表示されないことができgas_carたりhybrid_car、など

そのようなデザインに何か問題はありますか?将来発生する可能性のある問題はありますか?

回答:


59

さまざまなタイプの車は、データモデリングで何度も繰り返し現れる一般的な問題の例です。ERモデリングでは「一般化/特殊化」、オブジェクトモデリングでは「スーパークラス/サブクラス」と呼ばれます。

オブジェクトモデラーは、オブジェクトモデルに組み込まれた継承機能を使用して、問題を非常に簡単に解決します。サブクラスは単にスーパークラスを拡張します。

リレーショナルモデラーは問題に直面しています。継承から得られる利点をエミュレートするようにテーブルを設計する方法は?

最も単純な手法は、単一テーブル継承と呼ばれます。すべてのタイプの自動車に関するデータは、自動車用の単一のテーブルにグループ化されます。単一のタイプのすべての車をグループ化する列car_typeがあります。車は複数のタイプに属することはできません。列が電気自動車などに関係ない場合、電気自動車に関連する行にはNULLのままになります

このシンプルなソリューションは、小規模でシンプルなケースに適しています。多くのNULLが存在すると、ストレージのオーバーヘッドが少し増え、検索のオーバーヘッドが少し増えます。開発者は、ブール値テストがNULL入力可能列で実行される場合、SQLの3値のロジックを学習する必要がある場合があります。これは最初は困惑することがありますが、それに慣れるでしょう。

クラステーブルの継承と呼ばれる別の手法があります。この設計では、gas_car、electric_car、hybrid_carの個別のテーブルがあり、すべてのテーブルが結合されています。特定の種類の自動車に関するすべてのデータが必要な場合は、carテーブルを適切な特殊なテーブルに結合します。この設計ではNULLの数は少なくなりますが、より多くの結合を行います。この手法は、より大きく複雑な場合に適しています。

共有主キーと呼ばれる3番目の手法があります。この手法は、クラステーブルの継承と組み合わせてよく使用されます。サブクラスの専用テーブルには、主キーとして、carテーブルの対応するエントリの主キーのコピーがあります。このid列は、主キーと外部キーの両方として宣言できます。

これには、新しい車を追加するときに少し余分なプログラミングが必要になりますが、結合が簡単、簡単、高速になります。

スーパークラスとサブクラスは、実世界では常に発生します。恐れてはいけません。ただし、初期設計のパフォーマンスをテストしてください。最初の試みがシンプルで健全な場合、それを調整して速度を上げることができます。


3
わぁ、ありがとう!それは私が理解しようとしていたもののスポットです。クラステーブルの継承はまさに私が必要なもののようです。私の場合だけでなく、質問を完全にカバーしていると思うので、将来の読者のためにこれに対する受け入れられた答えを変更しました。
アーサータラソフ

6
ここで優れた回答。1つのヒント:これらの設計決定を完全に文書化します。どちらのルートを選択しても、誰かがデータベース構造を調べているかどうかは明らかではありませんPostgresなどの一部のデータベースでは、列、テーブルなどのメタデータとともにコメントをバインドできます
バジルブルク

電気自動車がハイブリッドカーにもならないようにするための制限に対処しません。そのためには別のテーブルが必要です。
jmoreno

2
あなたが正しいです。carテーブルにcar_typeフィールドを追加すると、完全な正規化から逸脱する代わりに、1つのタイプのみに属するように車を制限できます。適切なDBMSを使用すると、車が複数の特殊なテーブルに入力されるのを防ぐチェック制約を定義できます。その中にいくつかのオーバーヘッドがあります。新しい車を追加します。
ウォルターミッティ

@WalterMittyがcar_typeフィールドなしで、データを取得するときにどのテーブルが詳細を検索するかをどのように知るのでしょうか?特定のcarレコードに関するデータがあるテーブルを確認するには、3つのテーブルすべてを読む必要がありますか?
ジョシュパート

12

モデル化しようとしているデータの現実を反映するために必要な数のエンティティサブタイプをモデル内に持つことには、何の問題もありません。問題は、サブタイプが悪い習慣かどうかではありません。問題は、それが良いモデルであるかもしれませんか?

たとえば、あなたの例では、プラグインハイブリッドであるAudi A4 eTronのようなもので何をしますか?それは「電気自動車」ですか、それとも「ハイブリッド車」ですか?

あなたが自問しなければならない他の質問は、なぜあなたはまったくサブタイプしているのですか?サブタイプにはいくつの異なる述語がありますか?これらの述語はサブタイプ間で共有されていますか?状況は複雑になる可能性があります。

サブタイピングは、分類のためのデータベース設計では使用されません。コード、コードテーブルへの外部キー、またはフラグを使用して分類を行うことができます。サブタイピングは、対象のさまざまなタイプの異なる述語セットをモデル化するために使用されます。単に分類のためにサブタイプを使用している場合、それは悪い習慣です。

サブタイプが、データベースが重要とするものについて異なる述語セットを明確かつ明確にモデル化する場合、必要なサブタイプの数に関係なく、完全に優れたプラクティスです。


おかげで、私は自分のために何らかのトラップを設定していたのではないかと心配しました。私の問題は、サブタイプごとに多くの列があることです。一部はオーバーラップし、それらをcarテーブルに配置しますが、多くはサブタイプテーブルに配置しません。たとえば、車の種類の基本部分を保存するようなものになります。電気自動車のエンジンは、100個の部品、ガソリン車のエンジン75個の部品、およびハイブリッド125個の部品を含むことができます。50の部品は一般的に保存されているであろうcars50、25、及び75になりながら、electric_cargas_car、及びhybrid_carテーブル
アーサーTarasov
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.