Ciò si basa su un malinteso principale del funzionamento interno di Postgres e dei progetti EAV .
Se non disponi di centinaia di campi diversi o di un insieme dinamico di tipi di attributi, utilizza una singola tabella con tutte le colonne - fatta eccezione per normalizzazione del database
. Le colonne senza valore vengono riempite con NULL
.
Lo spazio di archiviazione nullo è molto economico , occupando 1 bit per colonna nella tabella per la bitmap nulla, generalmente allocata in unità di 8 byte per coprire 64 colonne. Vedi:
Una riga separata per un singolo l'attributo aggiuntivo occupa almeno altri 36 byte .
4 bytes item identifier 23 bytes heap tuple header 1 byte padding 8 bytes minimum row data size
In genere di più, a causa dell'imbottitura e del sovraccarico aggiuntivo.
Dovrebbero esserci centinaia di colonne diverse e scarsamente popolate prima che un design EAV così ingombrante possa pagare - e hstore
o jsonb
in Postgres 9.4 sarebbero soluzioni superiori per quello . Non c'è quasi spazio nel mezzo per il tuo design e se c'era, probabilmente avresti utilizzato un enum
per il tipo.
Allo stesso tempo, le query sono più complicate e costose. Siamo in una situazione difficile qui.
Usa invece un layout di tabella come questo:
CREATE TABLE users (
users_id serial PRIMARY KEY
, salutation text
, given_name text
, surname text
, alias text
... (many) more columns
);
CREATE TABLE address (
address_id serial PRIMARY KEY
, users_id int REFERENCES users
, city text -- or separate TABLE city incl region_id etc. ...
, region_id int REFERENCES region
, address text
... (many) more columns
);
Risposta strettamente correlata con più consigli: