我正在为商店,产品,客户,供应商和仓库等实体设计数据库。该数据库将用作不同实体店的在线交易系统。
在我的情况下,商店,客户,供应商和仓库的所有属性都可以定义为列,因为它们不会随着时间的推移而发生太大变化。然而,产品具有无限量的属性,因此我想将这些数据放入EAV模型中。
是否可以指出值是否应该放在他们自己的数据类型特定的表中(例如attribute_values_int,或者作为泛型attribute_value表中的列?由于性能原因,Magento选择了特定于数据类型的值表。请参阅:{ {3}}
感谢。
答案 0 :(得分:2)
hstore
字段,XML
或json
。
在PostgreSQL中,使用每个数据类型表没有性能优势。 NULL
值存储在紧凑的NULL
位图中,因此,如果您拥有(NULL, NULL, NULL, 42, NULL, NULL)
或(42)
这样的元组,则会产生很小的差异。
这也允许您添加CHECK
约束强制执行一个字段必须非NULL
,因此您不会获得不同类型的多个值。
演示:
regress=> CREATE TABLE eav_ugh (
entity_id integer,
int_value integer,
numeric_value numeric,
text_value text,
timestamp_value timestamp with time zone,
CONSTRAINT only_one_non_null CHECK (
(int_value IS NOT NULL AND numeric_value IS NULL AND text_value IS NULL AND timestamp_value IS NULL) OR
(int_value IS NULL AND numeric_value IS NOT NULL AND text_value IS NULL AND timestamp_value IS NULL) OR
(int_value IS NULL AND numeric_value IS NULL AND text_value IS NOT NULL AND timestamp_value IS NULL) OR
(int_value IS NULL AND numeric_value IS NULL AND text_value IS NULL AND timestamp_value IS NOT NULL)
)
);
CREATE TABLE
regress=> insert into eav_ugh (entity_id, numeric_value) select x, x from generate_series(1,5000) x;
INSERT 0 5000
regress=> select pg_relation_size('eav_ugh');
pg_relation_size
------------------
229376
(1 row)
regress=> CREATE TABLE no_null_cols(entity_id integer, numeric_value numeric);
CREATE TABLE
regress=> insert into no_null_cols (entity_id, numeric_value) select x, x from generate_series(1,5000) x;
INSERT 0 5000
regress=> select pg_relation_size('no_null_cols');
pg_relation_size
------------------
229376
(1 row)
regress=> SELECT sum(pg_column_size(eav_ugh)) FROM eav_ugh;
sum
--------
164997
(1 row)
regress=> SELECT sum(pg_column_size(no_null_cols)) FROM no_null_cols;
sum
--------
164997
(1 row)
在这种情况下,空位图根本不会添加任何空间,可能是由于对齐要求。