sql >> Database >  >> RDS >> PostgreSQL

Op zoek naar een juiste EAV-structuur op basis van jsonb

Doelstelling:u wilt een kenmerk opslaan dat gerelateerd is aan een bepaalde entiteit.

Ik raad geen aparte tabel aan voor attribuutwaarden zoals we dat in de afgelopen jaren misschien hebben gedaan. Zet een jsonb veld rechts op de juiste tabel en noem het Attributes . Voeg een GIN toe index, zodat u de waarden snel kunt opvragen. Of gebruik de andere technieken die hierin worden beschreven.

Lees dit:https://dba.stackexchange.com/a/174421/7762

De grootste vraag hier is of u van plan bent attribuutwaarden vooraf te definiëren. Als je dat doet, is er een uiterst efficiënte manier om ze op te slaan. Zo niet, dan raad ik een standaard JSON-object aan.

Als u de namen EN waarden van uw attributen vooraf kunt definiëren:

Dit geeft je de meeste controle, snelheid en toch flexibiliteit.

Maak een tabel Attribute die deze velden heeft:

  • AttributeID int4 unsigned not null primary key
  • ParentAttributeID int4 unsigned null
  • Name varchar(64) not null
  • Deleted bool niet null standaard false
  • Voeg een index toe aan ParentAttributeID
  • Voeg een trigger toe om AttributeID te voorkomen van veranderen
  • Voeg een regel toe voor verwijderen, stel in plaats daarvan Deleted=True in

Voeg vervolgens in elke tabel die u wilt toekennen dit veld toe:

Wat heeft dit bereikt?

Je hebt een boom met attributen gemaakt. Het kan er zo uitzien:

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

Stel dat je een tabel hebt met de naam Items en daarop heb je AttributeSet . toegevoegd :

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

Wanneer vertaald, betekent dit dat het de Color=Green . heeft attribuut, en de Size=Medium attribuut. 103 en 112 waren genoeg om dat op te slaan, maar soms is het leuk om te kunnen zeggen "Laat me alle items zien die een bepaalde grootte hebben", daarom was 110 inbegrepen.

Je kunt dit razendsnel en ultraflexibel maken.

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

Retourneert alle items met Size=Medium en Color=Green

Of u kunt de andere operators gebruiken op https://www.postgresql .org/docs/10/static/functions-array.html om met geweldige vragen te komen.

Als u de attribuutwaarden niet kent, maar het is een kleine set:

Dit geeft je de meeste snelheid, controle en is nog flexibeler. U kunt indien nodig nieuwe kenmerken markeren voor beoordeling.

U kunt de bovenstaande techniek gebruiken en gewoon dynamisch waarden toevoegen aan het Attribute tabel als ze niet bestaan.

Als u de attribuutwaarden niet kent en de waarden zijn divers

Dit geeft je de meeste flexibiliteit, maar gaat ten koste van de controle.

Voeg in dit geval dit toe aan een willekeurige tabel:

  • AttributeMap jsonb not null default '{}'::jsonb
  • Voeg een GIN-index toe aan dat veld

Schrijf code om de waarden te valideren tegen uw Attribute tafel. Heb daar een indicator of het een enkele of meervoudige waarde is...

Op deze manier opslaan in de AttributeMap veld:

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

Merk op dat Categorieën een multi-attribuut is. In uw Attribute tabel moet u een veld hebben dat IsMulti bool not null . is waarmee u weet hoe u ernaar kunt vragen.




  1. SQL rij-retourvolgorde

  2. UNIEKE beperking, alleen als een veld een specifieke waarde bevat

  3. Top 30 meest bruikbare gelijktijdige manager-query's

  4. MYSQL selecteer nieuwste berichten uit tabellen