1. ホーム
  2. database-design

[解決済み] 各製品が多くのパラメータを持つ多品種の製品テーブルを設計する方法

2022-05-04 04:35:28

質問事項

私はテーブルデザインの経験があまりありません。私の目標は、以下の要件を満たす1つまたは複数の製品テーブルを作成することです。

  • 多くの種類の製品(テレビ、電話、PC、...)をサポートする。製品の種類ごとに、次のような異なるパラメータのセットを持っています。

    • 携帯電話には、色、サイズ、重量、OS...があります。

    • PCは、CPU、HDD、RAM...。

  • パラメータのセットは動的である必要があります。好きなパラメータを追加したり編集したりすることができます。

製品の種類ごとに別々のテーブルを用意せずに、これらの要件を満たすにはどうしたらよいでしょうか?

どのように解決するのですか?

あなたが説明した型階層をモデル化するために、少なくとも以下の5つの選択肢があります。

  • 単一テーブル継承 : すべての製品タイプに対して1つのテーブルがあり、すべてのタイプのすべての属性を格納するのに十分なカラムがあります。 つまり たくさん のカラムがあり、そのほとんどは任意の行でNULLとなります。

  • クラステーブルの継承 : すべての製品タイプに共通する属性を格納する、製品用のテーブルを1つ作成します。 次に、製品タイプごとに1つのテーブルがあり、その製品タイプに固有の属性が格納されます。

  • 具体的なテーブルの継承 : 共通の商品属性用のテーブルはありません。 その代わり、商品タイプごとに1つのテーブルがあり、共通の商品属性と商品固有の属性の両方を格納する。

  • シリアル化されたLOB : すべての製品タイプに共通する属性を格納する、製品用の1つのテーブル。 追加のカラムには、XML、YAML、JSON、またはその他のフォーマットによる半構造化データの BLOB が格納されます。 このBLOBには、各商品タイプに固有の属性を格納することができます。 これを表現するために、FacadeやMementoのような凝ったデザインパターンを使用することができる。 しかし、SQLで簡単にクエリできない属性のブロブを持っていることに変わりはない。ブロブ全体をアプリケーションに取り込み、そこで整理しなければならない。

  • Entity-Attribute-Value : 商品のテーブルが1つ、そして属性を列ではなく行にピボットするテーブルが1つ。 EAVはリレーショナルパラダイムに関して有効な設計ではないが、とにかく多くの人がこれを使用している。 これは、他の回答で言及されている「プロパティ・パターン」です。 を使った他の質問も見てください。 eavタグ のStackOverflowに、いくつかの落とし穴があります。

これについては、プレゼンテーションで詳しく書いています。 拡張可能なデータモデリング .


EAVについての補足:多くの人がEAVを支持しているようですが、私はそうではありません。 EAVは最も柔軟なソリューションであり、それゆえベストであると思います。 しかし、次のような格言を覚えておいてください。 TANSTAAFL . ここでは、EAVのデメリットを紹介します。

  • カラムを必須とする方法がない(相当するのは NOT NULL ).
  • エントリーの検証に SQL データ型を使用する方法がない。
  • 属性名のスペルを統一する方法がない。
  • ルックアップテーブルのように、任意の属性の値に外部キーを設定する方法がない。
  • 従来の表形式レイアウトで結果を取得するのは、複雑でコストがかかります。 JOIN を各属性ごとに指定します。

EAVは柔軟性がある分、他の部分で犠牲を払う必要があり、おそらく元の問題を従来の方法で解決するのと同じくらい(あるいはそれ以上に)複雑なコードになってしまうでしょう。

そして、ほとんどの場合、その程度の柔軟性は必要ないのです。 OPの質問である商品タイプについては、商品タイプごとにテーブルを作成して商品固有の属性を設定する方がはるかにシンプルで、少なくとも同じ商品タイプのエントリについては一貫した構造を確保することができます。

EAVを使うのは、以下の場合だけです。 すべての行 は、潜在的に異なる属性のセットを持つことが許可されている必要があります。 商品タイプに限りがある場合、EAVは過剰なサービスです。 クラス・テーブル継承が私の第一候補です。


Update 2019: "多くのカスタム属性"問題の解決策としてJSONを使用する人々を見れば見るほど、その解決策が好きではなくなってきました。それは、特殊な JSON関数 をサポートします。JSONドキュメントを保存するために、通常の行と列で保存するよりも多くのストレージスペースが必要になる。

基本的に、これらの解決策はいずれもリレーショナル・データベースでは容易ではなく、効率的でもありません。可変属性を持つという考え方は、リレーショナル・セオリーとは根本的に相容れないものなのです。

結局のところ、どの解決策が最も悪いかによって、どちらかを選択しなければならないということです。 あなたの アプリを開発することができます。したがって、データベース設計を選択する前に、どのようにデータを照会するのかを知っておく必要があります。あるアプリケーションにはどのソリューションも最適かもしれないので、1つのソリューションを選ぶことはできません。