Erstellen einer EINZIGARTIGEN Einschränkung aus einem JSON-Objekt

8

Nehmen wir einige Beispiele für Tabellenvölker, die nur zwei Felder haben: id und data (json).

SELECT data FROM peoples ;
{"name": "Adam","pos":"DBA","age":22 }
{"name": "Alice","pos":"Security","age":33 }
{"name": "Bob","pos":"Manager","age":42 }

Ich möchte eine Einschränkung für das Feld "pos" erstellen, die eindeutig sein muss. Ich habe über das Internet nach JSON-Einschränkungen gesucht, aber keine Ergebnisse.

Wie kann ich mit diesem Problem umgehen?

Chenko47
quelle
6
JSON wird für schemalose, unstrukturierte Daten verwendet. Wenn Sie Einschränkungen wünschen, sollten Sie Ihre Daten ordnungsgemäß normalisieren.
a_horse_with_no_name
5
"Normalisieren, normalisieren, normalisieren!" (VI dezso)
dezso

Antworten:

16

In erster Linie: Ich stimme sowohl den Kommentaren von @a_horse_with_no_name als auch @dezso zu: Sie sollten Ihre Daten normalisieren . JSON ist nicht dafür.

Wenn jedoch ein Grund, den ich nicht ergründen kann, dies wirklich zu einem Vorteil macht, ist es möglich:

Erstellen Sie einen Ausdruck basierend aufUNIQUE INDEX :

CREATE UNIQUE INDEX people_data_pos_idx ON peoples( (data->>'pos') ) ;

Wenn Sie zu diesem Zeitpunkt versuchen, die folgenden Daten in Ihre Tabelle einzufügen (mit einer bereits vorhandenen - >> pos):

INSERT INTO peoples(data)
VALUES
    ('{"name": "Eve", "pos":"DBA", "age":34}') ;

Sie erhalten dies als Antwort:

ERROR: duplicate key value violates unique constraint "people_data_pos_idx"
SQL state: 23505
Detail: Key ((data ->> 'pos'::text))=(DBA) already exists.

HINWEIS: Ich habe angenommen, dass dies data.posimmer eine Zeichenfolge sein wird. Wenn Sie verallgemeinern möchten, können Sie ( (data->'pos') )stattdessen verwenden. Sie würden dann einen JSON (B) -Ausdruck anstelle eines Textes indizieren. Überprüfen Sie die JSON-Funktionen und -Operatoren .

joanolo
quelle