質問

と言っても過言ではありません。 EAV/CR データベースモデルが間違っています。そうは言っても、

質問: 実行時に変更できる電子商取引商品を記述する属性の「クラス」を処理するには、どのようなデータベース モデル、技術、またはパターンを使用する必要がありますか?

優れた電子商取引データベースでは、オプションのクラスを保存します (テレビの解像度のように、テレビごとに解像度がありますが、次の製品はテレビではなく、「テレビの解像度」がない可能性があります)。これらをどのように保存し、効率的に検索し、ユーザーが製品を説明する変数フィールドを使用して製品タイプを設定できるようにするにはどうすればよいでしょうか?顧客が通常、コンソールの深さに基づいてテレビを検索していることが検索エンジンによって判明した場合は、フィールドにコンソールの深さを追加し、実行時にテレビ製品タイプごとに 1 つの深さを追加できます。

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

さらなる議論:

長い話ですが、 次の設定を「学術的に」修正できるリンクやモデルの説明がインターネット上にありますか? カテゴリ表を提案してくれた Noel Kennedy に感謝しますが、必要性はそれ以上に大きいかもしれません。以下では、その重要性を強調するために、別の方法で説明します。問題を解決するには視点を修正する必要があるかもしれません。あるいは、EAV/CR をさらに深く掘り下げる必要があるかもしれません。

EAV/CR モデルに対する肯定的な反応が気に入っています。私の同僚の開発者は皆、Jeffrey Kemp が以下に触れたことについて述べています。「新しいエンティティは専門家によってモデル化および設計されなければなりません」(文脈から切り離して、以下の彼の返答を読んでください)。問題は:

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

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

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

属性には、単なるキーワード検索ではなく、重要な意味がなければなりません。「ホイップ クリームのフロスティング」が含まれるすべてのケーキを比較したい場合は、ケーキをクリックし、誕生日のテーマをクリックし、ホイップ クリームのフロスティングをクリックして、すべてにホイップ クリームのフロスティングがあることがわかっているので、興味深いケーキをすべてチェックします。これはケーキに特有のものではなく、単なる例です。

役に立ちましたか?

解決

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

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

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

オプション 2、各エンティティを個別にモデル化する:

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

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

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

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

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

他のヒント

  

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

いいえ、そうではありません。それは彼らが、リレーショナル・データベースの非効率的な使用方法だだけのことです。純粋にキー/値ストアは、このモデルで素晴らしい作品ます。

さて、あなたの本当の質問に:どのようにさまざまな属性を格納し、検索それらを保つ

ただ、EAVを使用します。あなたのケースでは、単一の余分なテーブルになります。属性名と値の両方のインデックスを、ほとんどのRDBMSが、それは本当に速いし、コンパクト化、属性名の繰り返し上にプレフィックス圧縮を使用することになります。

あなたは「実際の」フィールドを置き換えるためにそれを使用する場合、

EAV / CRは醜い取得します。すべてのツールと同じように、それを乱用することは「悪い」であり、そしてそれを悪いイメージを与えます。

// At this point, I'd like to take a moment to speak to you about the Magento/Adobe PSD形式.
// Magento/PSD is not a good ecommerce platform/フォーマット. Magento/PSD is not even a bad ecommerce platform/フォーマット. Calling it such would be an
// insult to other bad ecommerce platform/フォーマット, such as Zencart or OsCommerce. No, Magento/PSD is an abysmal ecommerce platform/フォーマット. Having
// worked on this code for several weeks now, my hate for Magento/PSD has grown to a raging fire
// that burns with the fierce passion of a million suns.

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

内部モデルは、よく言っても奇抜で、誰かがスキーマを泥沼ゲームに入れて封印し、ペイントシャッカーに入れたようなものです...

現実の世界:私はミッドウェア フルフィルメント アプリに取り組んでいます。アドレス情報を取得するためのクエリの 1 つを次に示します。

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. 痛みを楽しむ

私は誰ものNoSQLデータベースを言及していない驚いています。

私は本番コンテキストでのNoSQLを練習したことがありません(ただのMongoDBをテストし、感動しました)が、のNoSQLの全体のポイントは、同じ「文書」における様々な属性を持つアイテムを保存できることです。

の性能は、アプリケーションのETL型のように、主要な要件ではない、EAVは別の明確な利点を有する:差動節約

私は、オーバーアーチ要件は、それが現在の状態だと、その最初の「バージョン」からドメインオブジェクトの履歴を表示する機能だったアプリケーションの数を実装しました。そのドメイン・オブジェクト属性の数が多い場合、すなわち、各変更が新しい行を必要とすることは(履歴が失われるためではない更新が、インサート)は、対応する表の中に挿入することを意味します。のは、このドメインオブジェクトが人である、と私はさまざまな属性への人のライフサイクルにわたる100+変化の平均を追跡するための500k者を持っているとしましょう。レアは1つだけの主要なドメインオブジェクトを持って、あなたはすぐにデータベースのサイズが急速に制御不能に成長することをsurmizeだろうアプリケーションであるという事実とそのカップルます。

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

すべてのモデルは、新たなビジネス・ニーズを反映するために時間をかけて変化します。期間。 EAVを使用することであるが、使用するために私たちのボックス内のツールの一つ。それは、自動的に「悪い」と分類すべきではありません。

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

MagentoののEAV性能が本当の致命あること、らしい。

私は正規化された構造に傾いてる理由です。編集し、そしてそれに基づいてすることができ、私は将来(XMLまたは別のDBテーブル)で、いくつかの個別のデータ・ディクショナリを追加することを考えている柔軟性の欠如を克服するために、設定した新しい属性を持つ製品カテゴリを表示し、比較するためのアプリケーションコードは次のようになります一緒にSQLスクリプトを使用し、生成されます。

このようなアーキテクチャは、この場合にsweetspotと思わ - 同時に柔軟かつパフォーマンス

問題は、ライブ環境でALTER TABLEを頻繁に使用することができます。私はそのMVCCおよびトランザクションのDDLがうまくいけば、痛みを緩和します、Postgresのを使用しています。

私はまだEAVの最安-意味の原子レベルでのモデリングに投票します。

などの属性、穀物、の繰り返しの必要性、コンテンツモデルを決定するために、特定のユーザーコミュニティに向かってギアの基準、技術やアプリケーションをしてみましょう

これは、製品カタログの属性についてだけだとそれらの属性のため、したがって検証要件がかなり限られている、EAVへの唯一の本当の欠点は、クエリのパフォーマンスであってもそれが唯一の問題クエリが複数を扱う「もの」(製品)の場合最適ではないが、十分速いまだありながら属性で、クエリのパフォーマンスは、「私のID 234を持つ製品のすべての属性を与えます」。

一つの解決策は、製品カタログの管理/編集側のためのSQLデータベース/ EAVモデルを使用し、それが検索可能になり、何かに製品を非正規化し、いくつかのプロセスを持つことです。すでに属性を持っているので、それはあなたがファセットをしたいということではなく可能性がありますので、この何かがSolrのかElasticSearchである可能性があります。このアプローチはEAVモデルに基本的にすべての欠点を回避し、追加された複雑更新にJSONに完全な製品をシリアライズに制限されます。

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

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

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

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

EAV enter image description here

配列 enter image description here

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

判明したのは、 配列ベースのスキーマは一桁高速でした 挿入とクエリの両方に適用されます。簡単なテストによると、どちらも直線的にスケールされるようでした。ただし、テストはそれほど徹底的ではありません。提案やフォークは大歓迎です。それらは MIT ライセンスの下にあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top