Digamos que a entidade do produto da loja tenha características comuns, como nome, descrição, imagem, preço, etc., que participem da lógica de muitos lugares e tenha características (semi) únicas, como relógio e bola de praia, que seriam descritas por aspectos completamente diferentes . Então eu acho que o EAV seria adequado para armazenar esses recursos (semi) exclusivos?
O uso de uma estrutura EAV para tem várias implicações que são compensações.
Você está trocando um 'menos espaço para a linha porque não possui 100 colunas null
' contra 'consultas e modelos mais complexos'.
Ter um EAV normalmente significa que o valor é uma string na qual se pode inserir qualquer dado. Isso, então, tem implicações na verificação de validade e restrição. Considere a situação em que você colocou o número de baterias usadas como algo na tabela EAV. Você deseja encontrar uma lanterna que use baterias do tamanho C, mas menos de 4 delas.
select P.sku
from
products P
attrib Ab on (P.sku = Ab.sku and Ab.key = "batteries")
attrib Ac on (P.sku = Ac.sku and Ac.key = "count")
where
cast(Ac.value as int) < 4
and Ab.value = 'C'
...
O que você deve perceber aqui é que você não pode usar um índice razoavelmente no valor. Você também não pode impedir que alguém insira algo que não seja um número inteiro lá ou um número inteiro inválido (use baterias '-1') porque a coluna de valor é usada repetidamente para propósitos diferentes.
Isso tem implicações na tentativa de escrever um modelo para o produto. Você terá os bons valores digitados ... mas também ficará Map<String,String>
sentado lá com todo o tipo de coisas . Isso então tem implicações adicionais ao serializá-lo para XML ou Json e as complexidades de tentar validar ou consultar essas estruturas.
Algumas alternativas ou modificações no padrão a serem consideradas é, em vez de uma chave de forma livre, ter outra tabela com chaves válidas. Isso significa que, em vez de fazer comparações de strings no banco de dados, você está verificando a igualdade dos IDs de chave estrangeira. Alterar a chave em si é feito em um ponto. Você tem um conjunto conhecido de chaves, o que significa que elas podem ser feitas como uma enumeração.
Você também pode ter tabelas relacionadas que contêm atributos de uma classe específica de produto. Um departamento de mercearia pode ter outra tabela que possui vários atributos associados aos quais os materiais de construção não precisam (e vice-versa).
+----------+ +--------+ +---------+
|Grocery | |Product | |BuildMat |
|id (fk) +--->|id (pk) |<---+id (fk) |
|expiration| |desc | |material |
|... | |img | |... |
+----------+ |price | +---------+
|... |
+--------+
Há momentos em que especialmente requerem uma tabela EAV.
Considere a situação em que você não está apenas escrevendo um sistema de inventário para sua empresa, onde conhece todos os produtos e atributos. Agora você está escrevendo um sistema de inventário para vender para outras empresas. Você não pode conhecer todos os atributos de cada produto - eles precisarão defini-los.
Uma idéia que surge é "deixaremos o cliente modificar a tabela" e isso é péssimo (você entra em metaprogramação para estruturas de tabela porque não sabe mais o que é onde, eles podem realmente atrapalhar a estrutura ou corromper o aplicativo, eles têm acesso para fazer coisas erradas e as implicações desse acesso se tornam significativas). Há mais sobre esse caminho no MVC4: como criar modelo em tempo de execução?
Em vez disso, você cria a interface administrativa para uma tabela EAV e permite que ela seja usada. Se o cliente deseja criar uma entrada para 'polkadots', ela entra na tabela EAV e você já sabe como lidar com isso.
Um exemplo disso pode ser visto no modelo de banco de dados do Redmine. Você pode ver a tabela custom_fields e a tabela custom_values - essas são partes do EAV que permite a extensão do sistema.
Observe que, se você achar que toda a estrutura de sua tabela se parece com EAV, em vez de relacional, convém observar o sabor KV do NoSQL (cassandra, redis, Mongo, ...). Perceba que isso geralmente vem com outras desvantagens em seu design que podem ou não ser apropriadas para o que você está usando. No entanto, eles são projetados especificamente com a intenção de uma estrutura de EAV.
Você pode ler SQL vs NoSQL para um sistema de gerenciamento de inventário
Seguindo essa abordagem com um banco de dados NoSQL orientado a documentos (couch, mongo), você pode considerar cada item de inventário como um documento em um disco ... puxar tudo em um único documento é rápido. Além disso, o documento está estruturado para que você possa executar rapidamente qualquer coisa. Por outro lado, procurar em todos os documentos itens que correspondam a um atributo específico pode ter menos desempenho (compare usando 'grep' em todos os arquivos) ... é tudo uma troca.
Outra abordagem seria o LDAP, em que se teria uma base com todos os itens associados, mas também haveria classes de objetos adicionais aplicadas a ele para os outros tipos de itens. (consulte Inventário do sistema usando LDAP )
Depois de seguir esse caminho, você poderá encontrar algo que corresponda exatamente ao que está procurando ... embora tudo venha com algumas desvantagens.