ウェブサイトの製品データベースの更新に取り組んでいます。MySQLに組み込まれていますが、これは一般的なデータベース設計パターンの問題です。
Supertype / Subtypeパターンへの切り替えを計画しています。現在/以前のデータベースは、主に単一のタイプの製品に関するデータを含む単一のテーブルです。私たちは、異なる製品を含めるために製品提供を拡大することを検討しています。
この新しいドラフトデザインは次のようになります。
Product product_[type] product_attribute_[name]
---------------- ---------------- ----------------------------
part_number (PK) part_number (FK) attributeId (PK)
UPC specific_attr1 (FK) attribute_name
price specific_attr2 (FK)
... ...
製品の属性表について質問があります。ここでのアイデアは、色:赤、緑、青、または材料:プラスチック、木材、クロム、アルミニウムなどの特定の属性のリストを持つことができる製品です。
このリストはテーブルに格納され、その属性項目の主キー(PK)は特定の製品テーブルで外部キー(FK)として使用されます。
(Martin Fowler氏の著書「Patterns of Enterprise Application Architecture」では、これを「外部キーマッピング」と呼んでいます)
これにより、Webサイトインターフェースは、指定された属性タイプの属性のリストをプルし、ドロップダウン選択メニューまたはその他のUI要素にそれを吐き出すことができます。このリストは、属性値の「許可された」リストと考えることができます。
特定の製品をプルするときに発生する結合の数が多すぎるように見えます。すべての製品属性テーブルを製品に結合して、その属性のフィールドを取得できるようにする必要があります。一般的に、そのフィールドは、単にその名前の文字列(varchar)にすぎません。
この設計パターンでは、多数のテーブルが作成されるだけでなく、属性ごとにテーブルが作成されます。これに対抗する1つのアイデアは、すべての製品属性に対して「グラブバッグ」テーブルのようなものを作成することです。このようなもの:
product_attribute
----------------
attributeId (PK)
name
field_name
このようにすると、テーブルは次のようになります。
1 red color
2 blue color
3 chrome material
4 plastic material
5 yellow color
6 x-large size
これはテーブルのクリープを減らすのに役立ちますが、結合の数を減らすことはなく、非常に多くの異なるタイプを1つのテーブルに結合することは少し間違っているように感じます。ただし、使用可能なすべての「色」属性をかなり簡単に取得できます。
ただし、色のRGB値など、単なる「名前」よりも多くのフィールドを持つ属性がある場合があります。これには、特定の属性が別のテーブルを持っているか、名前と値のペアの単一のフィールドを持っている必要があります(これには独自の欠点があります)。
私が考えることができる最後のデザインパターンは、実際の属性値を特定の製品テーブルに格納し、「属性テーブル」をまったく持たないことです。このようなもの:
Product product_[type]
---------------- ----------------
part_number (PK) part_number (FK)
UPC specific_attr1
price specific_attr2
... ...
別のテーブルへの外部キーの代わりに、次のような実際の値が含まれます。
part_number color material
----------- ----- --------
1234 red plastic
これは結合を排除し、テーブルのクリープを防止します(たぶん?)。ただし、これにより、属性の「承認済みリスト」を作成できなくなります。特定のフィールド(つまり、色)に現在入力されているすべての値を返すこともできますが、これにより、特定の属性の値の「承認済みリスト」を作成する必要がなくなります。
そのリストを作成するには、「グラブバッグ」属性テーブルを作成するか、各属性に複数のテーブル(テーブルクリープ)を用意する必要があります。
これにより、製品名が複数の場所に配置されるという大きな欠点(そして私がこのアプローチを使用したことがない理由)が作成されます。
「マスター属性テーブル」に「赤」のカラー値があり、それを「product_ [type]」テーブルにも格納している場合、「マスター」テーブルを更新すると、アプリケーションがデータ整合性の問題を引き起こす可能性があります「product_type」テーブルの古い値ですべてのレコードも更新しません。
したがって、このシナリオの長い説明と分析の後で、私の認識は、これは珍しいシナリオではない可能性があり、このタイプの状況に名前が付けられることさえあるということです。
この設計課題に対する一般的に受け入れられている解決策はありますか?テーブルが比較的小さい場合、潜在的に多数の結合が許容されますか?状況によっては、属性PKの代わりに属性名を格納できますか?私が考えていない別の解決策はありますか?
この製品データベース/アプリケーションに関する注意事項:
- 製品が頻繁に更新/追加/削除されない
- 属性が頻繁に更新/追加/削除されない
- テーブルは、情報の読み取り/返却のために最も頻繁に照会されます
- サーバー側のキャッシュは、特定のクエリ/結果の結果をキャッシュするために有効になっています
- 私は1つの製品タイプから始めて、時間の経過とともに他の製品タイプを拡張/追加することを計画しており、潜在的に10以上の異なるタイプがあるでしょう