sql >> Database teknologi >  >> RDS >> Mysql

Skal jeg placere EAV-værdier i en datatypetabel?

Helt ærligt er den bedste mulighed "ikke EAV". Prøv at bruge hstore felter, XML eller json .

I PostgreSQL er der ingen ydeevnefordel ved at bruge tabeller pr. datatype. NULL værdier er gemt i en kompakt NULL bitmap, så det gør meget lidt forskel om du har en tuple som (NULL, NULL, NULL, 42, NULL, NULL) eller bare (42) .

Dette giver dig også mulighed for at tilføje CHECK begrænsning, der håndhæver, at præcis ét felt skal være ikke-NULL , så du ikke får flere værdier af forskellige typer.

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)

I dette tilfælde tilføjer null-bitmap ikke noget mellemrum overhovedet, sandsynligvis på grund af justeringskrav.




  1. hvordan man beregner den resterende tid med php og mysql?

  2. Hvor mange lige dage er der mellem to datointervaller, SQL

  3. Sådan fjerner du en database-mailkonto fra en profil i SQL Server (T-SQL)

  4. Lagring af binære datatyper i SQL Server