Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Czy powinienem umieścić wartości EAV w tabeli typów danych?

Szczerze mówiąc, najlepszą opcją jest „nie EAV”. Spójrz na użycie hstore pola, XML lub json .

W PostgreSQL nie ma żadnej przewagi wydajnościowej wynikającej z używania tabel z podziałem na typy danych. NULL wartości są przechowywane w kompaktowym NULL bitmapę, więc nie ma większego znaczenia, czy masz krotkę taką jak (NULL, NULL, NULL, 42, NULL, NULL) lub po prostu (42) .

Pozwala to również dodać CHECK ograniczenie wymuszające, że dokładnie jedno pole nie może mieć wartości NULL , dzięki czemu nie otrzymasz wielu wartości różnych typów.

Demo:

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)

W tym przypadku zerowa mapa bitowa w ogóle nie dodaje miejsca, prawdopodobnie ze względu na wymagania dotyczące wyrównania.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wyklucz rekordy, jeśli pasuje odpowiednia tabela

  2. Ukośniki w tabelach MySQL, ale przy użyciu PDO i sparametryzowanych zapytań. Co tam?

  3. MySQL kontra MariaDB:co musisz wiedzieć

  4. Nie można połączyć się z mysql pod w Kubernetes podczas używania obiektów tajnych jako hasła (odmowa dostępu)

  5. Wyłączenie wiersza w MySQL