sql >> Base de Datos >  >> RDS >> PostgreSQL

Buscando una estructura EAV correcta basada en jsonb

Objetivo:desea almacenar un atributo relacionado con una entidad dada.

No recomiendo una tabla separada para los valores de los atributos como podríamos haber hecho en años pasados. Poner un jsonb campo a la derecha en la tabla apropiada y llámelo Attributes . Añadir un GIN indexarlo para que pueda consultar los valores rápidamente. O use las otras técnicas descritas aquí.

Lea esto:https://dba.stackexchange.com/a/174421/7762

La pregunta más importante aquí es si tiene la intención de predefinir los valores de los atributos. Si lo hace, hay una manera extremadamente eficiente de almacenarlos. Si no, recomiendo un objeto JSON estándar.

Si puede predefinir los nombres Y valores de sus atributos:

Esto le brinda el máximo control, velocidad y aún brinda flexibilidad.

Crear una tabla Attribute que tiene estos campos:

  • AttributeID int4 unsigned not null primary key
  • ParentAttributeID int4 unsigned null
  • Name varchar(64) not null
  • Deleted bool no es nulo por defecto falso
  • Agregar un índice en ParentAttributeID
  • Agregue un activador para evitar AttributeID de cambiar
  • Agregue una regla sobre la eliminación en lugar de establecer Deleted=True

Luego, en cualquier tabla que desee atribuir, agregue este campo:

¿Qué ha logrado esto?

Ha creado un árbol de atributos. Podría verse así:

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 tiene una tabla llamada Items y en él has agregado AttributeSet :

      ItemID: 1234
        Name: Tee Shirt
AttributeSet: [100, 103, 110, 112]

Cuando se traduce, esto significa que tiene el Color=Green atributo, y el Size=Medium atributo. 103 y 112 fueron suficientes para almacenar eso, pero a veces es bueno poder decir "Muéstrame todos los elementos que tienen cualquier Tamaño definido", por eso se incluyó 110.

Puede hacer que sea ultraflexible y ultrarrápido.

SELECT
  "ItemID", "Name"
FROM
  "Items"
WHERE "AttributeMap" @> ARRAY[103,112]

Devolverá todos los artículos que tengan Size=Medium y Color=Green

O puede usar los otros operadores en https://www.postgresql .org/docs/10/static/functions-array.html para llegar a algunas consultas impresionantes.

Cuando no conoce los valores de los atributos pero es un conjunto pequeño:

Esto le brinda la mayor velocidad, control y es aún más flexible. Puede marcar nuevos atributos para su revisión si es necesario.

Puede usar la técnica anterior y simplemente agregar dinámicamente valores al Attribute tabla si no existen.

Cuando no conoce los valores de los atributos y los valores son diversos

Esto le brinda la mayor flexibilidad, pero a expensas del control.

En este caso, simplemente agregue esto a cualquier tabla:

  • AttributeMap jsonb not null default '{}'::jsonb
  • Agregue un índice GIN a ese campo

Escriba código para validar los valores contra su Attribute mesa. Tener un indicador allí si es un valor único o múltiple...

Almacenar así en el AttributeMap campo:

{
    "Color": "Green", 
    "Size": "Medium", 
    "Categories": ["Sports", "Leisure"]
}

Tenga en cuenta que Categorías es un atributo múltiple. En tu Attribute tabla debe tener un campo que sea IsMulti bool not null lo que te permitirá saber cómo consultarlo.