<p>私にはテーブル設計の経験があまりありません。私の目標は、次の要件を満たす 1 つ以上の製品テーブルを作成することです。 </p>
<li><p>複数の種類の製品 (テレビ、携帯電話、コンピュータなど) をサポートします。製品の各タイプには、次のような異なるパラメータのセットがあります。 </p>
<li><p>携帯電話には色、サイズ、重量、オペレーティング システムなどが異なります。 </p></li>
<li><p>コンピュータには CPU、ハードドライブ、メモリなどが搭載されています。 </p></li>
</ul><
<li><p>パラメータセットは動的である必要があります。任意のパラメータを追加または編集できます。 </p></li>
</ul>
<p>製品タイプごとに個別のテーブルを作成せずに、これらの要件を満たすにはどうすればよいでしょうか? </p>
###@石の心###
私は常に EAV と MVC を使用します。
@ビル・カービン
ここで言及したすべての内容:
私の意見では、このようにデータベースを使用することは、石で釘を打つようなものです。石を使って行うこともできますが、このアクティビティのために特別に設計された、より正確なハンマーを使用すべきではないでしょうか。
この問題は、データの一部に対して少数のクエリを実行し、それをテーブル レイアウトに処理することで解決できます。 600 GB の商品データがある場合でも、このテーブルから各行のデータを取得する必要がある場合は、バッチで処理できます。
さらに、クエリのパフォーマンスを向上させたい場合は、レポートやグローバル テキスト検索などの特定の操作を選択し、必要なデータを保存し、定期的に (30 分ごとなど) 再生成するインデックス テーブルを準備できます。
追加のデータ ストレージのコストについて心配する必要もありません。データ ストレージのコストは日々低くなっています。
アプリケーションによって実行される操作のパフォーマンスがまだ心配な場合は、いつでも Erlang、C、Go 言語を使用してデータを前処理し、メイン アプリケーションで最適化されたデータをさらに処理できます。
記述した型階層をモデル化するには、少なくとも次の 5 つのオプションがあります:
単一テーブルの継承: すべてのタイプのすべての属性を格納するのに十分な列を備えた、すべての製品タイプに対して 1 つのテーブルを使用します。これは、各行に多くの列があり、その行のほとんどが NULL であることを意味します。
クラス テーブルの継承: 製品のテーブルを使用して、すべての製品タイプの共通属性を保存します。次に、各製品タイプのテーブルを使用して、その製品タイプに固有の属性を保存します。
特定のテーブルの継承: 共通の製品属性のテーブルはありません。代わりに、製品タイプごとに 1 つのテーブルを使用して、共通の製品属性と製品固有の属性を保存します。
シリアル化された LOB: 製品に対して 1 つのテーブルを使用して、すべての製品タイプの共通属性を保存します。追加の列には、XML、YAML、JSON、またはその他の形式の半構造化データの BLOB が保存されます。この BLOB を使用すると、各製品タイプに固有の属性を保存できます。ファサードやメメントなど、複雑なデザイン パターンを使用してこのプロセスを記述することができます。ただし、いずれにせよ、SQL で簡単にクエリできないプロパティ BLOB があるため、BLOB 全体をアプリケーションに返し、そこで並べ替える必要があります。
Entity-Attribute-Value: 製品のテーブルと、属性を列ではなく行に回転させるテーブルを使用します。 EAV はリレーショナル パラダイムにおいて効率的な設計ではありませんが、今でも多くの人が使用しています。これは、別の回答で述べた「プロパティ パターン」です。問題点のいくつかについては、StackOverflow で eav タグ を使用した他の質問を確認してください。
これについては、Extensible Data Modeling というデモで詳しく書きました。
EAV についてのその他の考え: 多くの人は EAV を気に入っているようですが、私はそうではありません。これは最も柔軟なソリューションであるため、最良のソリューションであると思われます。ただし、この格言 TANSTAAFL を思い出してください。 EAV の欠点のいくつかを次に示します:
NOT NULL
と同等)。JOIN
が必要だからです。EAV によって提供される柔軟性には他の領域での犠牲が必要となり、元の問題を従来の方法で解決した場合と同じくらい (またはさらに悪化) コードが複雑になる可能性があります。
そして、ほとんどの場合、そのレベルの柔軟性は必要ありません。製品タイプに関するご質問では、製品固有の属性を格納するテーブルを製品タイプごとに作成する方が簡単です。これにより、同じ製品タイプのエントリに対して少なくとも一定の一貫した構造を適用できます。
各行 に異なるプロパティのセットを許可する場合にのみ、EAV を使用します。製品タイプのセットが限られている場合、EAV は過剰です。クラステーブルの継承が私の第一選択です。
2019 更新: 「多数のカスタム プロパティ」問題の解決策として JSON を使用している人を見るほど、私はこの解決策が好きではなくなります。特別な
JSON 関数 を使用してそれらをサポートしたとしても、クエリは複雑になりすぎます。 JSON ドキュメントを保存するには、通常の行と列に保存するよりも多くのストレージ スペースが必要です。
基本的に、リレーショナル データベースでは、これらのソリューションはどれも簡単でも効率的でもありません。 「可変特性」を持つという概念全体は、関係理論と根本的に矛盾します。アプリケーションにとって最も最悪のソリューションに基づいています。したがって、データベース設計を選択する前に、データをクエリする方法を知っておく必要があります。アプリケーションにとっては、いずれか 1 つのソリューションが最適な選択となる可能性があるため、1 つのソリューションが「最適」ということはありません。