Processamos um feed de dados de rotina de um cliente que acabou de refatorar seu banco de dados de um formulário que parece familiar (uma linha por entidade, uma coluna por atributo) para um que parece desconhecido para mim (uma linha por entidade por atributo):
Antes: uma coluna por atributo
ID Ht_cm wt_kg Age_yr ...
1 190 82 43 ...
2 170 60 22 ...
3 205 90 51 ...
Depois: uma coluna para todos os atributos
ID Metric Value
1 Ht_cm 190
1 Wt_kg 82
1 Age_yr 43
1 ...
2 Ht_cm 170
2 Wt_kg 60
2 Age_yr 22
2 ...
3 Ht_cm 205
3 Wt_kg 90
3 Age_yr 51
3 ...
Existe um nome para essa estrutura de banco de dados? Quais são as vantagens relativas? A maneira antiga parece mais fácil de colocar restrições de validade em atributos específicos (não nulos, não negativos, etc.) e mais fácil de calcular médias. Mas posso ver como pode ser mais fácil adicionar novos atributos sem refatorar o banco de dados. Esta é uma forma padrão/preferida de estruturar dados?
Chama-se Entidade-Atributo-Valor (às vezes também 'pares nome-valor') e é um caso clássico de "um pino redondo em um buraco quadrado" quando as pessoas usam o padrão EAV em um banco de dados relacional.
Aqui está uma lista de por que você não deve usar o EAV:
SELECT height, weight, age FROM Client where height is null or weight is null
.Comparar:
Para:
Aqui está uma lista (muito curta) de quando você deve usar o EAV:
Sei que acabei de passar este post inteiro detalhando por que o EAV é uma péssima ideia na maioria dos casos - mas há alguns casos em que é necessário/inevitável. no entanto, na maioria das vezes (incluindo o exemplo acima), será muito mais trabalhoso do que compensador. Se você tiver um requisito para amplo suporte de entrada de dados do tipo EAV, deve procurar armazená-los em um sistema de valor-chave, por exemplo, Hadoop/HBase, CouchDB, MongoDB, Cassandra, BerkeleyDB.
Valor do Atributo da Entidade (EAV)
É considerado um antipadrão por muitos, inclusive eu.
Aqui estão suas alternativas:
usar herança de tabela de banco de dados
usar dados XML e funções SQLXML
use um banco de dados nosql, como HBase
No PostgreSQL, uma forma muito boa de lidar com estruturas EAV é o módulo adicional
hstore
, disponível a partir da versão 8.4 ou posterior. O manual:Requer o módulo adicional hstore. Ver:
Desde o Postgres 9.2, há também o
json
tipo e uma série de funcionalidades para acompanhá-lo (a maior parte adicionada com o 9.3 ).O Postgres 9.4 adiciona o tipo de dados "JSON binário" (muito superior)
jsonb
. Com opções avançadas de índice.Engraçado ver como o modelo EAV db é criticado e até considerado um "anti-padrão" por alguns.
No que me diz respeito, as principais desvantagens são:
No entanto, você definitivamente não deve descartar esta solução, e aqui está o porquê:
Se você tiver um banco de dados que esteja usando a estrutura EAV, é possível consultar os dados de várias maneiras.
A resposta de @ Simon já mostra como realizar uma consulta usando várias junções.
Dados de amostra usados:
Se você estiver usando um RDBMS que tenha uma
PIVOT
função ( SQL Server 2005+ / Oracle 11g+ ), poderá consultar os dados da seguinte maneira:Consulte SQL Fiddle com demonstração
Se você não tiver acesso a uma
PIVOT
função, poderá usar uma função agregada com umaCASE
instrução para retornar os dados:Consulte SQL Fiddle com demonstração
Ambas as consultas retornarão dados no resultado: