sql >> Database >  >> RDS >> Mysql

Moet ik EAV-waarden in een datatypetabel plaatsen?

Eerlijk gezegd is de beste optie "niet EAV". Kijk naar het gebruik van hstore velden, XML , of json .

In PostgreSQL is er geen prestatievoordeel bij het gebruik van tabellen per gegevenstype. NULL waarden worden opgeslagen in een compacte NULL bitmap, dus het maakt weinig uit of je een tuple hebt zoals (NULL, NULL, NULL, 42, NULL, NULL) of gewoon (42) .

Hiermee kunt u ook CHECK . toevoegen beperking die afdwingt dat precies één veld niet-NULL . mag zijn , zodat u niet meerdere waarden van verschillende typen krijgt.

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)

In dit geval voegt de null-bitmap helemaal geen ruimte toe, waarschijnlijk vanwege uitlijningsvereisten.




  1. Entity Framework met mysql, probleem met tabelkapitalisatie tussen linux en Windows

  2. Hoe kunt u de tabellen van de dataset die u retourneert een naam geven in een opgeslagen proces?

  3. Mijn favoriete PostgreSQL-extensies - deel één

  4. Beveiliging tegen SQL-injectie - enkele aanhalingstekens