PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Auf der Suche nach einer richtigen EAV-Struktur basierend auf jsonb

Ziel:Sie möchten ein Attribut speichern, das sich auf eine bestimmte Entität bezieht.

Ich empfehle keine separate Tabelle für Attributwerte, wie wir es vielleicht in früheren Jahren getan haben. Fügen Sie ein jsonb ein Feld rechts auf der entsprechenden Tabelle und nennen Sie es Attributes . Fügen Sie einen GIN hinzu index darauf, damit Sie die Werte schnell abfragen können. Oder verwenden Sie die anderen darin beschriebenen Techniken.

Lesen Sie dies:https://dba.stackexchange.com/a/174421/7762

Die größte Frage hier ist, ob Sie beabsichtigen, Attributwerte vorzudefinieren. Wenn Sie dies tun, gibt es eine äußerst effiziente Möglichkeit, sie zu speichern. Wenn nicht, dann empfehle ich ein Standard-JSON-Objekt.

Wenn Sie die Namen UND Werte Ihrer Attribute vordefinieren können:

Dies gibt Ihnen die größte Kontrolle, Geschwindigkeit und bietet dennoch Flexibilität.

Erstellen Sie ein Tabellen-Attribute die diese Felder hat:

  • AttributeID int4 unsigned not null primary key
  • ParentAttributeID int4 unsigned null
  • Name varchar(64) not null
  • Deleted bool not null default false
  • Fügen Sie einen Index für ParentAttributeID hinzu
  • Fügen Sie einen Trigger hinzu, um AttributeID zu verhindern vor Änderungen
  • Fügen Sie eine Regel zum Löschen hinzu und setzen Sie stattdessen Deleted=True

Fügen Sie dann in jeder Tabelle, die Sie mit Attributen versehen möchten, dieses Feld hinzu:

Was hat das bewirkt?

Sie haben einen Baum von Attributen erstellt. Das könnte so aussehen:

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

Angenommen, Sie haben eine Tabelle mit dem Namen Items und darauf haben Sie AttributeSet hinzugefügt :

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

Übersetzt bedeutet das, dass es die Color=Green hat -Attribut und Size=Medium Attribut. 103 und 112 waren genug, um das zu speichern, aber manchmal ist es schön, sagen zu können "Zeig mir alle Artikel, für die eine beliebige Größe definiert ist", deshalb wurde 110 aufgenommen.

Sie können dies blitzschnell und ultraflexibel machen.

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

Gibt alle Artikel mit Size=Medium zurück und Color=Green

Oder Sie können die anderen Operatoren auf https://www.postgresql verwenden .org/docs/10/static/functions-array.html einige tolle Abfragen zu entwickeln.

Wenn Sie die Attributwerte nicht kennen, es sich aber um einen kleinen Satz handelt:

Dies gibt Ihnen die höchste Geschwindigkeit, Kontrolle und ist noch flexibler. Bei Bedarf können Sie neue Attribute zur Überprüfung melden.

Sie können die obige Technik verwenden und dem Attributes einfach dynamisch Werte hinzufügen Tabelle, falls sie nicht existieren.

Wenn Sie die Attributwerte nicht kennen und die Werte unterschiedlich sind

Das gibt Ihnen die größte Flexibilität, aber auf Kosten der Kontrolle.

Fügen Sie in diesem Fall einfach dies zu einer beliebigen Tabelle hinzu:

  • AttributeMap jsonb not null default '{}'::jsonb
  • Fügen Sie diesem Feld einen GIN-Index hinzu

Schreiben Sie Code, um die Werte anhand Ihres Attribute zu validieren Tisch. Haben Sie dort einen Indikator, ob es sich um einen Einzel- oder Mehrfachwert handelt ...

Speichern Sie so in der AttributeMap Feld:

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

Beachten Sie, dass Kategorien ein Mehrfachattribut ist. In Ihrem Attribute Tabelle sollten Sie ein Feld haben, das IsMulti bool not null ist Dadurch wissen Sie, wie Sie danach fragen können.