web-dev-qa-db-ja.com

属性ごとに複数の値を持つEAV

私は幅広いカテゴリー(テレビ、携帯電話、家具など)のeコマースWebサイトに取り組んでいます。属性が非常に多いため、EAVモデルを使用して属性と値を格納することにしました。これが私のテーブル構造です:

CREATE TABLE public.product_attribute
(
    name character varying(255) COLLATE pg_catalog."default",
    attribute_type character varying(255) COLLATE pg_catalog."default",
    id integer NOT NULL,
    CONSTRAINT product_attribute_pkey PRIMARY KEY (id)
)

CREATE TABLE public.product_attribute_value
(
    value_text text COLLATE pg_catalog."default",
    value_integer integer,
    value_boolean boolean,
    value_float double precision,
    value_richtext text COLLATE pg_catalog."default",
    value_date date,
    value_file character varying(255) COLLATE pg_catalog."default",
    value_image character varying(255) COLLATE pg_catalog."default",
    entity_object_id integer,
    attribute_id integer,
    product_id integer,
    id integer NOT NULL,
    CONSTRAINT product_attribute_value_pkey PRIMARY KEY (id),
    CONSTRAINT "product_attr_id" FOREIGN KEY (attribute_id)
        REFERENCES public.product_attribute (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)

新しいテレビを追加するとします。

Product
---------
id: 1
name: Sony TV

Product Attribute
-----------------
id: 1
name: Color

Product Attribute Value
-----------------------
id: 1
attribute_id: 1
value_text: white

私が直面している問題は、一部の製品(家具など)には同じ名前の属性(色など)が複数あることです。それだけでなく、画像の写真のURLも保存する必要があります。

Product
---------
id: 2
name: Table

Product Attribute Value
-----------------------
id: 3
attribute_id: 1
value_text: Pattern 1
value_image: 01/a0/01a0sdadasfsdfsdfasdfasfdfsafs.jpg
=======================
id: 4
attribute_id: 1
value_text: Pattern 2
value_image: 01/a2/01a234234234234234324324234234.jpg

すべての属性を持つ製品をフェッチするための最良の方法は何ですか?属性値でフィルタリングするためのクエリのパフォーマンスについてはあまり心配していません(すべてのデータがelasticsearchに同期され、そこからフェッチされるため)。しかし、数百万の製品があります。 1つのクエリ(1つの製品-> 1つの行)ですべての属性を持つ各製品をフェッチする方法はありますか?

JSONBは頻繁に更新され、何百万ものレコードを検索して更新して属性名の名前を変更したくないため、この属性を保存するのは最善の方法ではないと思います。

1
5w0rdf1sh

あなたの答え

同じ名前の複数の属性(たとえば、色)、

したがって、より具体的な別の属性を作成します。

画像の写真のURLも保存する必要があります。

これは単なる別の属性です...

_Product Attribute
-----------------
2 | photo_exterior

Product Attribute Value
-----------------------
id: 1
attribute_id: 2
value: 01/a0/01a0sdadasfsdfsdfasdfasfdfsafs.jpg
_

そうは言っても、私がしなければならないのでなければ、私はこれをしません。 JSONBを使用します。

すべての属性を持つ製品をフェッチするための最良の方法は何ですか?

どのような結果セットが必要かわかりません。 EAVをどのように照会しますか?あなたがそれを作ることができれば、あなたは確かにそれから結果セットを得るために結合をすることができます。

1つのクエリ(1つの製品-> 1つの行)ですべての属性を持つ各製品をフェッチする方法はありますか?

はい、属性の数がわからない場合は、hstoreまたはjsonbを使用することになります。 jsonb_agg() を参照してください

X-Y問題?

JSONBを再評価し、命を救うために速度を調べる。 100万個の製品を作成し、jsonbを使用して属性の名前を変更します。

_CREATE TABLE products(id,name,data)
AS
        SELECT x, 'foo'::text, jsonb_build_object('color', 'blue') AS data
        FROM generate_series(1,1e6) AS gs(x);


UPDATE products
SET data = data-'color' || jsonb_build_object('colour', data->'color');
Time: 5063.010 ms
_

SSDを搭載したx230ラップトップ。それは197行/ミリ秒ですか?それよりも速く更新する必要があるAmazonを再作成していますか?

2
Evan Carroll