Isso se baseia em um equívoco principal do funcionamento interno do Postgres e dos projetos EAV .
Se você não tiver centenas de campos diferentes ou um conjunto dinâmico de tipos de atributos, use uma tabela única com todas as colunas - exceto para normalização de banco de dados . Colunas sem valor são preenchidas com
NULL
.O armazenamento nulo é muito barato , ocupando 1 bit por coluna na tabela para o bitmap nulo, normalmente alocado em unidades de 8 bytes para cobrir 64 colunas. Ver:
- Quanto espaço em disco é necessário para armazenar um valor NULL usando o banco de dados postgresql?
Uma linha separada para um único atributo adicional ocupa pelo menos um 36 bytes adicional .
4 bytes item identifier 23 bytes heap tuple header 1 byte padding 8 bytes minimum row data size
Normalmente mais, devido ao preenchimento e sobrecarga adicional.
Teria que haver centenas de colunas diferentes e pouco preenchidas antes que um design EAV tão pesado pudesse pagar - e
hstore
ou jsonb
no Postgres 9.4 seriam soluções superiores para isso . Quase não há espaço para o seu design e se havia, você provavelmente estaria usando um enum
para o tipo. Ao mesmo tempo, as consultas são mais complicadas e caras. Estamos em uma situação difícil aqui.
Em vez disso, use um layout de tabela como este:
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
);
Resposta intimamente relacionada com mais conselhos: