Création d'une contrainte UNIQUE à partir d'un objet JSON

8

Prenons quelques exemples de peuples de table, qui n'ont que 2 champs: id et data (json).

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

Je veux créer une contrainte pour le champ "pos", qui doit être unique. J'ai cherché sur Internet sur les contraintes JSON mais aucun résultat.

Comment gérer ce problème?

Chenko47
la source
6
JSON est utilisé pour les données non structurées et non structurées. Si vous souhaitez des contraintes, vous devez normaliser correctement vos données.
a_horse_with_no_name
5
"Normaliser, normaliser, normaliser!" (VI dezso)
dezso

Réponses:

17

Tout d'abord: je suis d'accord avec les commentaires de @a_horse_with_no_name et @dezso: vous devez normaliser vos données . JSON n'est pas pour ça.

Cependant, si une raison que je ne peux pas comprendre en fait vraiment un avantage, il est possible:

Créez une expression basée surUNIQUE INDEX :

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

Si, à ce stade, vous essayez d'insérer les données suivantes dans votre table (avec un - >> pos déjà existant):

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

Vous obtenez ceci en réponse:

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

REMARQUE: j'ai supposé que ce data.possera toujours une chaîne. Si vous souhaitez généraliser, vous pouvez utiliser à la ( (data->'pos') )place. Vous indexeriez alors une expression JSON (B) au lieu d'un texte. Vérifiez les fonctions et opérateurs JSON .

joanolo
la source