Mysql
 sql >> база данни >  >> RDS >> Mysql

Трябва ли да поставя EAV стойности в таблица с типове данни?

Честно казано, най-добрият вариант е "не EAV". Разгледайте използването на 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)

В този случай нулевата растерна карта изобщо не добавя пространство, вероятно поради изисквания за подравняване.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL- оптимизиран case оператор

  2. Изчислете децил от честотата в MySQL

  3. MySql пълно присъединяване (обединение) и подреждане на множество колони за дата

  4. SQL:Къде между две дати без година?

  5. Параметризирани заявки PHP/MySQL