sql >> Databáze >  >> RDS >> Mysql

Mám umístit hodnoty EAV do tabulky datových typů?

Upřímně řečeno, nejlepší možností je „ne EAV“. Podívejte se na použití hstore pole, XML nebo json .

V PostgreSQL není žádná výkonnostní výhoda při použití tabulek podle datových typů. NULL hodnoty jsou uloženy v kompaktním NULL bitmap, takže je velmi malý rozdíl, zda máte n-tici jako (NULL, NULL, NULL, 42, NULL, NULL) nebo jen (42) .

To také umožňuje přidat CHECK omezení vynucující, že právě jedno pole musí být jiné než NULL , takže nezískáte více hodnot různých typů.

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)

V tomto případě nulová bitmapa nepřidává vůbec žádné místo, pravděpodobně kvůli požadavkům na zarovnání.




  1. Oracle na PostgreSQL:ZAČNĚTE S / PŘIPOJTE SE

  2. Vyberte s více značkami

  3. Seznam účtů přidružených k profilu pošty databáze na serveru SQL Server

  4. Interní chyba serveru Django 500 – nesprávně nakonfigurovaná:Chyba při načítání modulu MySQLdb: