Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 我应该将EAV值放在数据类型表中吗?_Mysql_Postgresql_Database Design_Entity Attribute Value - Fatal编程技术网

Mysql 我应该将EAV值放在数据类型表中吗?

Mysql 我应该将EAV值放在数据类型表中吗?,mysql,postgresql,database-design,entity-attribute-value,Mysql,Postgresql,Database Design,Entity Attribute Value,我正在为商店、产品、客户、供应商和仓库等实体设计一个数据库。该数据库将在不同的实体商店中用作在线交易系统 在我的例子中,商店、客户、供应商和仓库的所有属性都可以定义为列,因为它们不会随时间发生太大的变化。然而,这些产品有无限数量的属性,所以我想把这些数据放在一个EAV模型中 有人能指出这些值是否应该放在他们自己的特定于数据类型的表中(如attribute_values_int,或作为通用属性_value表中的列?由于性能原因,Magento选择了特定于数据类型的值表。请参阅: 谢谢。坦率地说,最

我正在为商店、产品、客户、供应商和仓库等实体设计一个数据库。该数据库将在不同的实体商店中用作在线交易系统

在我的例子中,商店、客户、供应商和仓库的所有属性都可以定义为列,因为它们不会随时间发生太大的变化。然而,这些产品有无限数量的属性,所以我想把这些数据放在一个EAV模型中

有人能指出这些值是否应该放在他们自己的特定于数据类型的表中(如attribute_values_int,或作为通用属性_value表中的列?由于性能原因,Magento选择了特定于数据类型的值表。请参阅:


谢谢。

坦率地说,最好的选择是“非EAV”。请考虑使用
hstore
字段、
XML
json

在PostgreSQL中,使用每种数据类型的表没有性能优势。
NULL
值存储在一个紧凑的
NULL
位图中,因此无论您使用的是
(NULL,NULL,NULL,42,NULL,NULL)
还是
(42)
这样的元组,都没有什么区别

这还允许您添加
检查
约束,强制一个字段必须是非
空的
,这样您就不会得到不同类型的多个值

演示:


在这种情况下,空位图根本没有添加任何空间,这可能是由于对齐要求。

如果我错了,请纠正我,但如果您发布一个链接,说明出于性能原因,magento使用了特定类型的表。答案不是很明显吗?如果您不使用特定类型的表,您最终会将所有内容添加到varchar/text列中。如果需要,您需要一个元数据表来解释属性的存储位置(在int、float、char表中)。@N.B.谢谢您的评论,但我也可以创建一个具有不同列(value\u int、value\u datetime等)的值表。我希望您能解释为什么特定于数据类型的选项会带来更好的性能,至少在Magento的情况下是这样?因为如果您使用特定于数据类型的表,并且可以在有意义的地方对某些数据类型表进行索引,您将节省更多的空间。这并不是一种性能提升,因为它可以减轻您对att属性将适合于值列。想象一下,一个EAV设计有一个值表,您存储的数据可以是一个1位数字或一大块文本。您被迫使用
text
类型,以便可以存储任何内容。或者您可以创建一个特定于类型的表,而不必担心“一网打尽”表及其用于存储值的列。但是,对于一个具有多个列的单值表,每个数据类型一列如何?我真的看不到向查询添加联接的好处(除了每行几个NULL之外)当您仍然可以索引、排序和筛选,因为数据类型在列中定义时?@Hans仅在必要时向EAV模型添加额外的值表。想象一下,当您有3-5个单独的值表时,在实体“abc”上查询
获取属性“xyz”的值。
。感谢您在放置所有值时指出了Craig在单个表中的列中,您知道不先检查数据类型就可以进行选择吗?以便db返回非空的列值?如果可能的话,我可以想象这比先检查数据类型快得多。当然,我们在选择日期计算的行时会遇到问题。@Hans:不,不是;这是一个问题(很多)原因我讨厌EAV,更喜欢使用诸如hstore、json或xml字段之类的内容。好吧,我必须研究hstore、xml和json的可能性,因为我的属性链接到一个配置表。我不知道这样做是否可行。@hans如果你的意思是通过“链接”将外键插入那么不,目前您不能从hstore/json/xml键到查找表的外键引用。事实上,出于性能和一致性原因,属性和配置表之间应该有一个外键。
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)