首页 文章

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

提问于
浏览
0

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

在我看来,商店,客户,供应商和仓库的所有属性都可以定义为列,因为它们不会随着时间的推移而发生太大变化 . 但是,产品具有无限量的属性,因此我想将此数据放入EAV模型中 .

任何人都可以指出值是应该放在他们自己的数据类型特定的表中(例如attribute_values_int,还是作为泛型attribute_value表中的列?由于性能原因,Magento选择了特定于数据类型的值表 . 请参阅:http://blog.magestore.com/2012/03/23/magento-certificate-eav-model-concepts

谢谢 .

1 回答

  • 2

    坦率地说,最好的选择是"not EAV" . 查看使用 hstore 字段, XMLjson .

    在PostgreSQL中,使用每个数据类型表没有性能优势 . NULL 的值存储在一个紧凑的 NULL 位图中,因此无论你有像_2555465这样的元组还是只有 (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)
    

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

相关问题