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

Leder efter en rigtig EAV-struktur baseret på jsonb

Formål:Du vil gemme attributter relateret til en given enhed.

Jeg anbefaler ikke en separat tabel for attributværdier, som vi kunne have gjort i de forgangne ​​år. Indsæt en jsonb felt lige på den relevante tabel og kald det Attributes . Tilføj en GIN indeks til det, så du hurtigt kan forespørge værdierne. Eller brug de andre teknikker beskrevet heri.

Læs dette:https://dba.stackexchange.com/a/174421/7762

Det største spørgsmål her er, om du har til hensigt at foruddefinere attributværdier. Hvis du gør det, er der en yderst effektiv måde at opbevare dem på. Hvis ikke, så anbefaler jeg et standard JSON-objekt.

Hvis du kan foruddefinere dine attributnavne OG værdier:

Dette giver dig mest kontrol, hastighed og giver stadig fleksibilitet.

Opret en tabel Attribute som har disse felter:

  • AttributeID int4 unsigned not null primary key
  • ParentAttributeID int4 unsigned null
  • Name varchar(64) not null
  • Deleted bool ikke null standard false
  • Tilføj et indeks på ParentAttributeID
  • Tilføj en trigger for at forhindre AttributeID fra at ændre sig
  • Tilføj en regel om sletning, sæt i stedet Deleted=True

Tilføj derefter dette felt i enhver tabel, du vil tilskrive:

Hvad har dette opnået?

Du har oprettet et træ af attributter. Det kan se sådan ud:

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

Lad os sige, at du har en tabel kaldet Items og på den har du tilføjet AttributeSet :

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

Når det er oversat, betyder det, at det har Color=Green attributten og Size=Medium attribut. 103 og 112 var nok til at gemme det, men nogle gange er det rart at kunne sige "Vis mig alle varer, der har en hvilken som helst størrelse defineret", derfor var 110 inkluderet.

Du kan gøre denne lynhurtig og ultra fleksibel.

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

Vil returnere alle varer, der har Size=Medium og Color=Green

Eller du kan bruge de andre operatorer på https://www.postgresql .org/docs/10/static/functions-array.html at komme med nogle fantastiske forespørgsler.

Når du ikke kender attributværdierne, men det er et lille sæt:

Dette giver dig mest hastighed, kontrol og er endnu mere fleksibel. Du kan markere nye attributter til gennemgang, hvis det er nødvendigt.

Du kan bruge ovenstående teknik og blot dynamisk tilføje værdier til Attribute tabel, hvis de ikke findes.

Når du ikke kender attributværdierne, og værdierne er forskellige

Dette giver dig den største fleksibilitet, men på bekostning af kontrol.

I dette tilfælde skal du blot tilføje dette til en hvilken som helst tabel:

  • AttributeMap jsonb not null default '{}'::jsonb
  • Tilføj et GIN-indeks til det felt

Skriv kode for at validere værdierne mod din Attribute bord. Har en indikator der, hvis det er en enkelt eller multi-værdi...

Gem sådan i AttributeMap felt:

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

Bemærk, at kategorier er en multi-attribut. I din Attribute tabel skal du have et felt, der er IsMulti bool not null som giver dig mulighed for at vide, hvordan du spørger efter det.




  1. Hvordan kan jeg forhindre logvækst i SQL Server, når jeg indsætter millioner af poster

  2. mysql ændring af innodb_large_prefix

  3. Sådan sammenkædes strenge i MySQL med CONCAT()

  4. Fuldtekstforespørgsel med et enkelt citat