sql >> Databasteknik >  >> RDS >> PostgreSQL

Letar efter en rätt EAV-struktur baserad på jsonb

Mål:Du vill lagra attribut relaterat till en given enhet.

Jag rekommenderar inte en separat tabell för attributvärden som vi kan ha gjort under år som gått. Sätt en jsonb fältet direkt på lämplig tabell och kalla det Attributes . Lägg till ett GIN indexera till det så att du snabbt kan fråga värdena. Eller använd de andra teknikerna som beskrivs i.

Läs detta:https://dba.stackexchange.com/a/174421/7762

Den största frågan här är om du tänker fördefiniera attributvärden. Om du gör det finns det ett extremt effektivt sätt att lagra dem. Om inte, rekommenderar jag ett standard JSON-objekt.

Om du kan fördefiniera dina attributnamn OCH värden:

Detta ger dig mest kontroll, snabbhet och ger dig fortfarande flexibilitet.

Skapa en tabell Attributes som har dessa fält:

  • AttributeID int4 unsigned not null primary key
  • ParentAttributeID int4 unsigned null
  • Name varchar(64) not null
  • Deleted bool inte null default false
  • Lägg till ett index på ParentAttributeID
  • Lägg till en utlösare för att förhindra AttributeID från att ändras
  • Lägg till en regel om borttagning, ställ istället in Deleted=True

Lägg sedan till det här fältet i valfri tabell som du vill tillskriva:

Vad har detta åstadkommit?

Du har skapat ett träd med attribut. Det kan se ut så här:

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

Säg att du har en tabell som heter Items och på den har du lagt till AttributeSet :

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

När den översätts betyder det att den har Color=Green attributet och Size=Medium attribut. 103 och 112 räckte för att lagra det, men ibland är det trevligt att kunna säga "Visa mig alla föremål som har någon storlek definierad", det var därför 110 ingick.

Du kan göra denna blixtsnabb och extremt flexibel.

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

Kommer att returnera alla varor som har Size=Medium och Color=Green

Eller så kan du använda de andra operatorerna på https://www.postgresql .org/docs/10/static/functions-array.html att komma med några fantastiska frågor.

När du inte känner till attributvärdena men det är en liten uppsättning:

Detta ger dig mest hastighet, kontroll och är ännu mer flexibel. Du kan flagga nya attribut för granskning om det behövs.

Du kan använda ovanstående teknik och bara dynamiskt lägga till värden till Attribute tabell om de inte finns.

När du inte känner till attributvärdena och värdena är olika

Detta ger dig mest flexibilitet, men på bekostnad av kontrollen.

I det här fallet lägg bara till detta i valfri tabell:

  • AttributeMap jsonb not null default '{}'::jsonb
  • Lägg till ett GIN-index i det fältet

Skriv kod för att validera värdena mot ditt Attributes tabell. Har en indikator där om det är ett enskilt eller flera värden...

Lagra så här i AttributeMap fält:

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

Observera att kategorier är ett multiattribut. I ditt Attributes tabell bör du ha ett fält som är IsMulti bool not null vilket gör att du kan veta hur du frågar efter det.




  1. Parameter Sniffing (eller Spoofing) i SQL Server

  2. MariaDB SYSTEM_USER() Förklarad

  3. tecken 0xc286 i UTF-8-kodning har ingen motsvarighet i WIN1252....Vid konvertering med iconv kraschar postgres restore

  4. Hibernate JPA, MySQL och TinyInt(1) för Boolean istället för bit eller char