PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Alla ricerca di una corretta struttura EAV basata su jsonb

Obiettivo:desideri memorizzare l'attributo relativo a una determinata entità.

Non consiglio una tabella separata per i valori degli attributi come avremmo potuto fare negli anni passati. Inserisci un jsonb campo a destra della tabella appropriata e chiamalo Attributes . Aggiungi un GIN index ad esso in modo da poter interrogare rapidamente i valori. Oppure usa le altre tecniche descritte all'interno.

Leggi questo:https://dba.stackexchange.com/a/174421/7762

La domanda più grande qui è se intendi predefinire i valori degli attributi. Se lo fai, c'è un modo estremamente efficiente per conservarli. In caso contrario, consiglio un oggetto JSON standard.

Se puoi predefinire i nomi E i valori dei tuoi attributi:

Questo ti offre il massimo controllo, velocità e flessibilità.

Crea una tabella Attribute che ha questi campi:

  • AttributeID int4 unsigned not null primary key
  • ParentAttributeID int4 unsigned null
  • Name varchar(64) not null
  • Deleted bool not null default false
  • Aggiungi un indice su ParentAttributeID
  • Aggiungi un trigger per impedire AttributeID dalla modifica
  • Aggiungi una regola sull'eliminazione, invece imposta Deleted=True

Quindi in qualsiasi tabella che desideri attribuire, aggiungi questo campo:

Che cosa ha ottenuto questo risultato?

Hai creato un albero di attributi. Potrebbe assomigliare a questo:

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

Supponiamo di avere una tabella chiamata Items e su di esso hai aggiunto AttributeSet :

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

Quando tradotto, significa che ha il Color=Green e l'attributo Size=Medium attributo. 103 e 112 erano sufficienti per memorizzarlo, ma a volte è bello poter dire "Mostrami tutti gli articoli che hanno una taglia definita", ecco perché è stato incluso 110.

Puoi renderlo veloce e ultra flessibile.

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

Restituirà tutti gli articoli che hanno Size=Medium e Color=Green

Oppure puoi utilizzare gli altri operatori su https://www.postgresql .org/docs/10/static/functions-array.html per fare delle domande fantastiche.

Quando non conosci i valori degli attributi ma è un piccolo insieme:

Questo ti dà la massima velocità, controllo ed è ancora più flessibile. Se necessario, puoi contrassegnare nuovi attributi per la revisione.

Puoi usare la tecnica sopra e semplicemente aggiungere dinamicamente valori all'Attribute tabella se non esistono.

Quando non conosci i valori degli attributi ei valori sono diversi

Questo ti offre la massima flessibilità, ma a scapito del controllo.

In questo caso, aggiungilo a qualsiasi tabella:

  • AttributeMap jsonb not null default '{}'::jsonb
  • Aggiungi un indice GIN a quel campo

Scrivi il codice per convalidare i valori rispetto al tuo Attribute tavolo. Avere un indicatore lì se si tratta di un valore singolo o multiplo...

Memorizza in questo modo nella AttributeMap campo:

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

Si noti che Categorie è un multiattributo. Nel tuo Attribute tabella dovresti avere un campo che sia IsMulti bool not null che ti permetterà di sapere come interrogarlo.