ショップ製品のエンティティを考えてみましょう。名前、説明、画像、価格など、ロジックの多くの場所に参加する共通の機能があり、時計やビーチボールはまったく異なる側面で説明される(半)固有の機能があります。EAVはそれらの(半)固有の機能を保存するのに適していると思いますか?
EAV構造を使用すると、トレードオフとなるいくつかの影響があります。
null
「より複雑なクエリとモデル」に対して「100の列がない」ため、「行のスペースが少なくなります」。
EAVがあるということは、通常、値が任意のデータを挿入できる文字列であることを意味します。これは、有効性と制約チェックに影響を及ぼします。EAVテーブルに何かとして使用するバッテリーの数を入れた状況を考えてみましょう。Cサイズのバッテリーを使用する懐中電灯を探しますが、そのうち4つ未満です。
select P.sku
from
products P
attrib Ab on (P.sku = Ab.sku and Ab.key = "batteries")
attrib Ac on (P.sku = Ac.sku and Ac.key = "count")
where
cast(Ac.value as int) < 4
and Ab.value = 'C'
...
ここで気づくのは、値に対して合理的にインデックスを使用できないことです。また、値列はさまざまな目的で何度も使用されるため、誰かがそこに整数ではないものや無効な整数(「-1」バッテリーを使用)を入れないようにすることはできません。
これは、製品のモデルを作成しようとすることに影響を及ぼします。あなたは素敵な型付けされた値を持っているでしょう...しかし、あなたはMap<String,String>
そこにあらゆる種類のものをそこにただ座っていることになるでしょう。これは、XMLまたはJsonにシリアル化するときにさらに意味を持ち、それらの構造に対して検証またはクエリを実行しようとする複雑さを伴います。
考慮すべきパターンのいくつかの代替または変更は、有効なキーを持つ別のテーブルを持つための自由形式キーの代わりです。これは、データベースで文字列を比較する代わりに、外部キーIDが等しいかどうかをチェックしていることを意味します。キー自体の変更は、1つの場所で行われます。既知のキーのセットがあるため、enumとして実行できます。
特定の製品クラスの属性を含む関連テーブルを作成することもできます。食料品部門には、建築資材に必要のない(およびその逆の)属性が関連付けられた別のテーブルがあります。
+----------+ +--------+ +---------+
|Grocery | |Product | |BuildMat |
|id (fk) +--->|id (pk) |<---+id (fk) |
|expiration| |desc | |material |
|... | |img | |... |
+----------+ |price | +---------+
|... |
+--------+
特に EAVテーブルが必要な場合があります。
会社の在庫システムを書いているだけではなく、すべての製品と属性を知っている状況を考えてください。これで、他の会社に販売する在庫システムを作成しています。すべての製品のすべての属性を知ることはできません -それらを定義する必要があります。
出てくる一つの考え方は、もはやどこで何を知っているので、あなたは彼らができる、テーブル構造のメタプログラミングに入るん(「私たちは、顧客がテーブルを変更してもらおう」と、これは単に悪いです丁重台無し構造を、または破損しアプリケーション、彼らは間違ったことをするためのアクセス権を持っているし、そのアクセスの意味が重要になります)。MVC4でこのパスについて詳しく説明しています。実行時にモデルを作成する方法は?
代わりに、EAVテーブルへの管理インターフェイスを作成し、それを使用できるようにします。顧客が「polkadots」のエントリを作成する場合、EAVテーブルに移動し、その対処方法を既に知っています。
この例はRedmineのデータベースモデルで見ることができます。custom_fieldsテーブルとcustom_valuesテーブルを見ることができます。これらはシステムを拡張できるEAVの一部です。
テーブル構造全体がリレーショナルではなくEAVのように見える場合は、NoSQLのKVフレーバー(cassandra、redis、Mongoなど)を調べてください。これらの設計には、使用目的に適している場合と適切でない場合がある他のトレードオフがしばしば伴うことを認識してください。ただし、これらはEAV構造の意図を持って特別に設計されています。
在庫管理システムのSQLとNoSQLを読むことをお勧めします。
ドキュメント指向のNoSQLデータベース(カウチ、mongo)を使用したこのアプローチに従って、各インベントリアイテムをディスク上のドキュメントと見なすことができます。1つのドキュメント内のすべてをすばやく取得できます。さらに、ドキュメントは構造化されているため、1つのものをすばやく取り出すことができます。一方、特定の属性に一致するものをすべてのドキュメントで検索すると、パフォーマンスが低下する可能性があります(すべてのファイルに対して 'grep'を使用して比較してください)...すべてのトレードオフです。
別のアプローチとしては、LDAPがあります。LDAPでは、関連するすべてのアイテムを含むベースがありますが、他のタイプのアイテムには追加のオブジェクトクラスが適用されます。(LDAPを使用したシステムインベントリを参照)
このパスをたどると、探しているものと完全に一致するものが見つかるかもしれません...すべてにいくつかのトレードオフがあります。