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