web-dev-qa-db-ja.com

製品タイプごとに個別のテーブルを作成するかどうか。

私はデータベースを設計している最中であり、私の最初の設計決定について考え直しています...

製品タイプは次のとおりです...モデル、部品、交換部品キット、オプション。

オプションA(最初の設計):上記の製品タイプ用に個別のテーブルを用意する予定でした。各テーブルでフィールドの約75%が同じになると思います。

それぞれの製品タイプの間に関連付ける必要があるため、各製品タイプを別々のテーブルとして作成しました。たとえば、モデルは多くのオプションを持つことができ、オプションは多くのモデルを持つことができます。オプションは多くのパーツを持つことができ、パーツは多くのオプションを持つことができます...など...

オプションB:個別のテーブルを作成する代わりに、モデル、パーツ、交換パーツキット、オプションを含むProductというテーブルを作成できます。モデルやオプションなどを区別するために、typeというフィールドを1つ持つことができます。特定の製品タイプでは、いくつかのフィールドが使用されない(nullのままになる)と思います。これが「ベストプラクティスではない」ことが関係する場所だと思います。

オプションBは、db設計の複雑さを大幅に軽減します。クエリのためにデータを引き出すときに、たくさんのテーブルを参照することを心配する必要もありません...

25
payling

これが私の設計上の決定である場合、私はおそらく「オプションC」(変更されたオプションa)をさらに使用します。

まず、なぜ「オプションB」ではないのですか。

1つには、各製品に独自のテーブルが提供されている明快さを気に入っています。型を判別するためのフィールドを持つすべてが1つの大きなテーブルである場合、関係はそれほど明確ではありません。

別の方法として、インデックス付け戦略では、常にその型フィールドをリストする必要があります。 4種類しかないため、インデックスのカーディナリティは非常に低くなります(SELECT * FROM product_table WHERE type='X'はとにかく基本的に全表スキャンを行っています)

オプションC

  • すべてのタイプが共有する列のみを保持する親テーブルを作成します
  • 各商品タイプを個別の列を持つ独自のテーブルとして作成します。1つ追加:親テーブルへのリンク
  • 各「リンク」テーブルを作成します:Product_Option、Model_optionなど、それぞれのキーへのリンクを使用します。
  • 相互リンク(MODEL_OPTION、OPTION_MODEL)を使用する場合は、これらのテーブルも作成してください。これにより、それを見る人にとって、結合がより明確になります。

欠点は、物事が更新または削除されるときに孤立を回避し、最初にこれらのテーブルを使用するクエリを設計する複雑さです。

8
Derek Downey

「正しい」リレーショナルモデル、オプションAから始めることをお勧めします。そのモデルの一般的な使用法が一部の領域で非正規化につながる場合は、そうすることを恐れないでください。

先週、私は同僚と、スキーマの設計がどのようにして固定されたものであり、決して変更できないものであると見なされるかについて話し合いました。奇妙なことに、アプリケーションの他のすべてのレイヤーでリファクタリングがどのように受け入れられているかを考えると、データベーススキーマのリファクタリングは依然として非現実的であると見なされています。

データベースへのインターフェースが適切に設計されている場合は、システムの使用パターンについてさらに学習しても、スキーマの適応を妨げるものは何もありません。

7

これは、Paul Neilsenが Chapter 17 of で説明しているBills of materials/multiple cardinalalityheirarcyと非常によく似ていますSQL Server 2008聖書

この章全体は非常に読みやすく、多対多の問題に対処する特定のセクションは416〜419ページにあります。

これは、分解パーツタイプのデータ設計に関して私が見た中で最高の議論です。

4つの製品タイプすべてにまたがるクエリが頻繁に発生する可能性のあるシナリオを想像できる場合(そして私にはそれがありそうです)、オプションBが最適です。

Productテーブルに多くの未使用のnull許容フィールドを残すのではなく、ModelProductテーブル、PartProductテーブル、ReplacementPartKitProductテーブルを追加して、それらのテーブルでそれらのタイプに対して異なるフィールドだけを用意しませんか?これらのテーブルでは、Productテーブルと同じ主キーを使用します。モデルを操作する場合は、ProductテーブルとModelProductテーブルを結合します。お持ちの製品レコードがパーツであるかどうかを判断する必要がありますか? ProductからPartProductへの左結合を実行するだけで、PartProduct。[PrimaryKey]がnullでなければ、Partが作成されます。 nullの場合、パーツではありません。または、ProductテーブルにProductTypeフィールドを追加することもできます。

0
Alan McBee