web-dev-qa-db-ja.com

エンティティ属性値データベースと厳密なリレーショナルモデルeコマース

EAV/CR データベースモデルが悪いと言っても安全です。とはいえ、

質問:実行時に変更できるeコマース製品を記述する属性の「クラス」を処理するには、どのデータベースモデル、手法、またはパターンを使用する必要がありますか?

優れたEコマースデータベースに、オプションのクラスを保存します(TV解像度の場合、各テレビの解像度がありますが、次の製品はテレビではなく「TV解像度」がない場合があります)。それらをどのように保存し、効率的に検索し、ユーザーが製品を説明する可変フィールドを持つ製品タイプを設定できるようにしますか?顧客が通常、コンソールの深さに基づいてテレビを検索していることが検索エンジンで検出された場合、フィールドにコンソールの深さを追加し、実行時に各テレビ製品タイプに単一の深さを追加できます。

優れたeコマースアプリには、一連の製品を表示し、「ドリルダウン」サイドメニューがあり、ヘッダーとして「TV解像度」を表示できるニースの一般的な機能があります。セットが見つかりました。いずれかをクリックすると、その解像度のテレビのみが表示されるため、サイドメニューで他のカテゴリを選択してさらにドリルダウンできます。これらのオプションは、実行時に追加される動的な製品属性です。

さらなる議論:

要するに、以下の設定を「学術的に」修正する可能性のあるリンクやモデルの説明がインターネット上にありますか?提案をしてくれたノエル・ケネディに感謝しますカテゴリテーブルですが、必要性はそれよりも大きい場合があります。以下に別の方法で説明し、重要性を強調します。問題を解決するために視点の修正が必要になる場合があります。または、EAV/CRをさらに深くする必要がある場合があります。

EAV/CRモデルに対する肯定的な反応が大好きです。私の仲間の開発者は皆、ジェフリー・ケンプが以下に触れたことを言います:「新しいエンティティはプロによってモデル化され、設計されなければなりません」(文脈から外れて、以下の彼の応答を読んでください)。問題は:

  • エンティティは毎週属性を追加および削除します
    (検索キーワードは将来の属性を決定します)
  • 新しいエンティティは毎週到着します
    (製品は部品から組み立てられます)
  • 古いエンティティは毎週消えます
    (アーカイブ済み、人気が低い、季節限定)

顧客は、次の2つの理由で製品に属性を追加したいと考えています。

  • 部門/キーワード検索/類似製品間の比較表
  • チェックアウト前の消費者製品構成

キーワード検索だけでなく、属性には重要性が必要です。 「ホイップクリームフロスティング」を持つすべてのケーキを比較したい場合は、ケーキをクリックし、誕生日のテーマをクリックし、ホイップクリームフロスティングをクリックしてから、すべてのケーキがホイップクリームフロスティングであることを確認してください。これは単なるケーキではなく、単なる例です。

131
Zachary Scott

私が考えることができるいくつかの一般的な長所と短所があり、一方が他方より優れている状況があります:

オプション1、EAVモデル:

  • プロ:シンプルなアプリケーションを設計および開発する時間を短縮
  • Pro:新しいエンティティは簡単に追加できます(ユーザーが追加することもできますか?)
  • プロ:「汎用」インターフェースコンポーネント
  • 短所:単純なデータ型の検証に必要な複雑なコード
  • 短所:単純なレポートのためのはるかに複雑なSQL
  • 欠点:複雑なレポートはほとんど不可能になります
  • 欠点:大規模なデータセットのパフォーマンスが低い

オプション2、各エンティティを個別にモデリング:

  • 短所:要件と設計を収集するのにより多くの時間が必要
  • 短所:新しいエンティティは、プロがモデル化および設計する必要があります
  • 短所:各エンティティのカスタムインターフェイスコンポーネント
  • プロ:実装が簡単なデータ型の制約と検証
  • メリット:SQLは簡単に記述、理解、デバッグできます
  • 利点:最も複雑なレポートでも比較的簡単です
  • プロ:大規模なデータセットで最高のパフォーマンス

オプション3、組み合わせ(モデルエンティティは「適切に」、ただし一部またはすべてのエンティティのカスタム属性に「拡張」を追加)

  • 賛否両論:オプション1よりも要件と設計を収集するのに時間がかかりますが、おそらくオプション2ほど長くはありません*
  • 短所:新しいエンティティは、プロがモデル化および設計する必要があります
  • プロ:新しい属性は後から簡単に追加できます
  • 欠点:単純なデータ型を検証するために必要な複雑なコード(カスタム属性用)
  • 欠点:カスタムインターフェイスコンポーネントはまだ必要ですが、カスタムアトリビュートには汎用インターフェイスコンポーネントが使用できる場合があります
  • 欠点:カスタム属性がレポートに含まれるとすぐにSQLが複雑になります
  • 短所:カスタム属性による検索またはカスタム属性によるレポートを開始する必要がない限り、一般的に良好なパフォーマンス

*オプション3が設計段階で必ず時間を節約するかどうかはわかりません。

個人的には、オプション2に傾いて、可能な限りEAVを避けます。ただし、一部のシナリオでは、ユーザーはEAVに付属する柔軟性が必要です。しかし、これには多大な費用がかかります。

74
Jeffrey Kemp

EAV/CRデータベースモデルが悪いと言っても安全です。

いいえ、ちがいます。リレーショナルデータベースを非効率的に使用しているだけです。純粋なキー/値ストアは、このモデルでうまく機能します。

さて、あなたの本当の質問:さまざまな属性を保存し、検索可能な状態に保つ方法は?

EAVを使用するだけです。あなたの場合、それは単一の追加テーブルになります。属性名と値の両方にインデックスを付けると、ほとんどのRDBMは属性名の繰り返しにプレフィックス圧縮を使用するため、非常に高速でコンパクトになります。

EAV/CRを使用して「実際の」フィールドを置き換えると、見苦しくなります。すべてのツールと同様に、使いすぎると「悪い」ものになり、悪いイメージを与えます。

62
Javier

誰もNoSQLデータベースに言及していないことに驚いています。

実稼働環境でNoSQLを実践したことはありません(MongoDBをテストしたばかりで感銘を受けました)。

15
Lucas T
 //この時点で、Magento /についてお話したいと思います/Adobe PSD形式。
 // Magento /PSD 良いeコマースプラットフォームではありません/フォーマット。 Magento /PSD 悪いeコマースプラットフォームでもない/フォーマット。そのような呼び出しは、
 //他の悪いeコマースプラットフォームへのin辱になります/フォーマット、ZencartやOsCommerceなど。いいえ、Magento /PSD ひどいeコマースプラットフォーム/フォーマット。 
 //このコードに数週間取り組んだ今、Magento /が嫌いです/PSD 猛烈な火に成長しました
 //百万の太陽の激しい情熱で燃えます。

http://code.google.com/p/xee/source/browse/trunk/XeePhotoshopLoader.m?spec=svn28&r=11#107

内部モデルはせいぜい奇抜です。誰かがスキーマをボッグルゲームに入れ、それを封印し、ペイントシャッカーに入れるように...

実世界:私はミドルウェアフルフィルメントアプリを開発していますが、ここに住所情報を取得するためのクエリを示します。

CREATE OR REPLACE VIEW sales_flat_addresses AS
SELECT sales_order_entity.parent_id AS order_id, 
       sales_order_entity.entity_id, 
       CONCAT(CONCAT(UCASE(MID(sales_order_entity_varchar.value,1,1)),MID(sales_order_entity_varchar.value,2)), "Address") as type, 
       GROUP_CONCAT( 
         CONCAT( eav_attribute.attribute_code," ::::: ", sales_order_entity_varchar.value )
         ORDER BY sales_order_entity_varchar.value DESC
         SEPARATOR '!!!!!' 
       ) as data
  FROM sales_order_entity
       INNER JOIN sales_order_entity_varchar ON sales_order_entity_varchar.entity_id = sales_order_entity.entity_id
       INNER JOIN eav_attribute ON eav_attribute.attribute_id = sales_order_entity_varchar.attribute_id
   AND sales_order_entity.entity_type_id =12
 GROUP BY sales_order_entity.entity_id
 ORDER BY eav_attribute.attribute_code = 'address_type'

注文の正確な住所情報を遅延して

-

要約:以下の場合にのみMagentoを使用します:

  1. あなたは大きなお金の袋を与えられています
  2. 絶対です
  3. 痛みを楽しむ
15
Vee

ETLタイプのアプリケーションのように、パフォーマンスが主要な要件ではない場合、EAVには別の明確な利点があります:差分保存。

私は、包括的な要件が最初の「バージョン」から現在の状態までのドメインオブジェクトの履歴を表示する機能である多くのアプリケーションを実装しました。そのドメインオブジェクトに多数の属性がある場合、変更ごとに対応するテーブルに新しい行を挿入する必要があります(履歴が失われるため更新ではなく、挿入)。このドメインオブジェクトがPersonであり、Personsのライフサイクル全体でさまざまな属性に対する平均100以上の変更を追跡する50万人のPersonがあるとします。それに、主要なドメインオブジェクトが1つしかないアプリケーションはまれであるという事実と相まって、データベースのサイズが急速に制御不能になってしまうことがすぐにわかります。

簡単な解決策は、冗長な情報を繰り返し保存するのではなく、主要なドメインオブジェクトに対する差分の変更のみを保存することです。

すべてのモデルは、新しいビジネスニーズを反映して時間とともに変化します。期間。 EAVを使用することは、使用するツールの1つにすぎません。ただし、自動的に「不良」として分類されることはありません。

11
Jerry Jasperson

私は同じ問題に苦しんでいます。既存の2つのeコマースソリューションであるMagento(EAV)とJoomla(通常のリレーショナル構造)に関する次の議論をチェックするのは興味深いかもしれません: https://forum.virtuemart.net/index.php?topic= 58686.

MagentoのEAVのパフォーマンスは、本当に目を見張るもののようです。

それが、正規化された構造に傾いている理由です。柔軟性の不足を克服するために、将来編集可能な別のデータディクショナリ(XMLまたは別のDBテーブル)を追加することを考えています。それに基づいて、製品カテゴリを表示し、新しい属性セットと比較するアプリケーションコードはSQLスクリプトと共に生成されます。

この場合、そのようなアーキテクチャはスイートスポットのようです-同時に柔軟性とパフォーマンスがあります。

問題は、ライブ環境でALTER TABLEを頻繁に使用することです。私はPostgresを使用しているので、MVCCとトランザクションDDLが痛みを和らげることを願っています。

3
aaimnr

私は今でも、EAVの最も意味のない原子レベルでのモデリングに投票しています。特定のユーザーコミュニティを対象とした標準、技術、およびアプリケーションに、コンテンツモデル、属性の反復ニーズ、グレインなどを決定させます。

2
Amanda Xu

製品カタログ属性についてだけであり、したがってそれらの属性の検証要件がかなり制限されている場合、EAVの唯一の本当の欠点はクエリのパフォーマンスであり、クエリが属性を持つ複数の「モノ」(製品)を処理する場合でも問題になります。 「id 234の製品のすべての属性を指定してください」というクエリのパフォーマンスは最適ではありませんが、それでも十分に高速です。

1つの解決策は、製品データベースの管理/編集側にのみSQLデータベース/ EAVモデルを使用し、製品を検索可能にするものに非正規化するプロセスを用意することです。すでに属性があり、ファセット化が必要になる可能性が高いため、これはSolrまたはElasticSearchになります。このアプローチにより、基本的にEAVモデルのすべての欠点が回避され、追加される複雑さは、更新時に完全な製品をJSONにシリアル化することに限定されます。

2
bob

EAVには多くの欠点があります。

  1. 時間の経過に伴うパフォーマンスの低下アプリケーション内のデータ量が特定のサイズを超えると、そのデータの取得と操作の効率が低下する可能性があります。
  2. SQLクエリは非常に複雑で、記述が困難です。
  3. データ整合性の問題。必要なすべてのフィールドに外部キーを定義することはできません。
  4. 独自のメタデータを定義および維持する必要があります。
2
Gabriel Voinea

私にはわずかに異なる問題があります:スパース値を持つ多くの属性の代わりに(おそらくEAVを使用する正当な理由です)、スプレッドシートのようなものを保存したいです。シートの列は変更できますが、シート内ではすべてのセルにデータが含まれます(スパースではありません)。

小さなテストセット を作成して、2つの設計のベンチマークを行いました。1つはEAVを使用し、もう1つはPostgres ARRAYを使用してセルデータを保存します。

[〜#〜] eav [〜#〜]enter image description here

Arrayenter image description here

両方のスキーマには適切な列にインデックスがあり、インデックスはプランナーによって使用されます。

挿入とクエリの両方で 配列ベースのスキーマが1桁高速だった であることが判明しました。簡単なテストから、両方が線形にスケーリングされたように見えました。ただし、テストはあまり徹底的ではありません。提案とフォークは歓迎します-それらはMITライセンスです。

1
z0r