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:
AttributeSet" int[] not null default
- Lägg till ett GIN-index på det matrisfältet
- Aktivera även
intarray
tillägg från https://www.postgresql.org/docs/current/static /intarray.html
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.