web-dev-qa-db-ja.com

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

たとえば、テーブルcarは、テーブルelectric_cargas_car、およびhybrid_carと1対1の関係にあります。 carelectric_carの場合、gas_carhybrid_carなどには表示されなくなります。

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

39
Arthur Tarasov

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

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

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

最も簡単な手法は 単一テーブル継承 と呼ばれます。すべてのタイプの自動車に関するデータは、自動車の単一のテーブルにグループ化されます。 1つのタイプのすべての自動車をグループ化する列car_typeがあります。車は複数のタイプに属することができません。列が、たとえば電気自動車と無関係の場合、電気自動車に関連する行には [〜#〜] null [〜#〜] が残ります。

このシンプルなソリューションは、小さくてシンプルなケースに適しています。 NULLが多数存在すると、ストレージのオーバーヘッドが少し増え、検索のオーバーヘッドが少し増えます。開発者は、ブール値のテストがnull許容列で行われる場合、 SQL 3値論理 を学習する必要がある場合があります。これは最初は不可解かもしれませんが、それに慣れます。

クラステーブル継承 と呼ばれる別のテクニックがあります。この設計では、すべてのテーブルの組み合わせであるcarに加えて、gas_car、electric_car、およびhybrid_carの個別のテーブルがあります。特定の種類の車に関するすべてのデータが必要な場合は、carテーブルを適切な専用テーブルに結合します。この設計ではNULLは少なくなっていますが、より多くの結合を行います。この手法は、より大規模で複雑な場合に適しています。

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

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

スーパークラスとサブクラスは、現実の世界では常に発生しています。恐れるな。ただし、初期設計のパフォーマンスをテストしてください。最初の試みが単純で健全であれば、微調整してスピードを上げることができます。

60
Walter Mitty

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

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

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

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

サブタイプが、データベースが扱う事柄について異なる述語セットを明確かつ明確にモデル化している場合、必要なサブタイプの数に関係なく、完全に良い方法です。

12
Joel Brown