PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Procurando uma estrutura EAV correta baseada em jsonb

Objetivo:você deseja armazenar o atributo relacionado a uma determinada entidade.


Eu não recomendo uma tabela separada para valores de atributos como poderíamos ter feito em anos passados. Coloque um jsonb campo direito na tabela apropriada e chame-o de Attributes . Adicione um GIN indexe para que você possa consultar os valores rapidamente. Ou use as outras técnicas descritas.

Leia isto:https://dba.stackexchange.com/a/174421/7762

A maior questão aqui é se você pretende pré-definir valores de atributos. Se você fizer isso, existe uma maneira extremamente eficiente de armazená-los. Caso contrário, recomendo um objeto JSON padrão.

Se você pode pré-definir os nomes E valores dos seus atributos:


Isso oferece mais controle, velocidade e ainda oferece flexibilidade.

Crie uma tabela Attribute que tem esses campos:
  • AttributeID int4 unsigned not null primary key
  • ParentAttributeID int4 unsigned null
  • Name varchar(64) not null
  • Deleted bool não nulo padrão falso
  • Adicione um índice em ParentAttributeID
  • Adicione um acionador para evitar AttributeID de mudar
  • Adicione uma regra para excluir, em vez disso, defina Deleted=True

Em seguida, em qualquer tabela que você deseja atribuir, adicione este campo:

O que isso conseguiu?

Você criou uma árvore de atributos. Pode parecer assim:
ID   Parent  Name
----------------------------
100  NULL    Color
101  100       Blue
102  100       Red
103  100       Green
110  NULL    Size
111  110       Large
112  110       Medium 
113  110       Small

Digamos que você tenha uma tabela chamada Items e nele você adicionou AttributeSet :
      ItemID: 1234
        Name: Tee Shirt
AttributeSet: [100, 103, 110, 112]

Quando traduzido, significa que tem o Color=Green atributo e o atributo Size=Medium atributo. 103 e 112 foram suficientes para armazenar isso, mas às vezes é bom poder dizer "Mostre-me todos os itens que têm qualquer Tamanho definido", por isso 110 foi incluído.

Você pode tornar este relâmpago rápido e ultra flexível.
SELECT
  "ItemID", "Name"
FROM
  "Items"
WHERE "AttributeMap" @> ARRAY[103,112]

Retornará todos os itens que tenham Size=Medium e Color=Green

Ou você pode usar os outros operadores em https://www.postgresql .org/docs/10/static/functions-array.html para fazer algumas perguntas impressionantes.

Quando você não conhece os valores dos atributos, mas é um conjunto pequeno:


Isso lhe dá mais velocidade, controle e é ainda mais flexível. Você pode sinalizar novos atributos para revisão, se necessário.

Você pode usar a técnica acima e apenas adicionar valores dinamicamente ao Attribute tabela se eles não existirem.

Quando você não conhece os valores dos atributos e os valores são diversos


Isso oferece mais flexibilidade, mas às custas do controle.

Nesse caso, basta adicionar isso a qualquer tabela:
  • AttributeMap jsonb not null default '{}'::jsonb
  • Adicione um índice GIN a esse campo

Escreva o código para validar os valores em relação ao seu Attribute tabela. Tenha um indicador lá se é um valor único ou múltiplo ...

Armazene assim no AttributeMap campo:
{
    "Color": "Green", 
    "Size": "Medium", 
    "Categories": ["Sports", "Leisure"]
}

Observe que Categories é um atributo múltiplo. Em seu Attribute table você deve ter um campo que seja IsMulti bool not null que permitirá que você saiba como consultá-lo.