PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Créer une contrainte unique avec des colonnes nulles

Créer deux index partiels :

CREATE UNIQUE INDEX favo_3col_uni_idx ON favorites (user_id, menu_id, recipe_id)
WHERE menu_id IS NOT NULL;

CREATE UNIQUE INDEX favo_2col_uni_idx ON favorites (user_id, recipe_id)
WHERE menu_id IS NULL;

De cette façon, il ne peut y avoir qu'une seule combinaison de (user_id, recipe_id)menu_id IS NULL , implémentant efficacement la contrainte souhaitée.

Inconvénients possibles :

  • Vous ne pouvez pas avoir de clé étrangère référençant (user_id, menu_id, recipe_id) . (Il semble peu probable que vous vouliez une référence FK large de trois colonnes - utilisez plutôt la colonne PK !)
  • Vous ne pouvez pas baser CLUSTER sur un index partiel.
  • Requêtes sans WHERE correspondant la condition ne peut pas utiliser l'index partiel.

Si vous avez besoin d'un complet index, vous pouvez également déposer le WHERE état de favo_3col_uni_idx et vos exigences sont toujours appliquées.
L'index, qui comprend maintenant toute la table, chevauche l'autre et s'agrandit. En fonction des requêtes typiques et du pourcentage de NULL valeurs, cela peut être utile ou non. Dans des situations extrêmes, il peut même être utile de maintenir les trois index (les deux partiels et un total en haut).

C'est une bonne solution pour une colonne nullable unique , peut-être pour deux. Mais cela devient rapidement incontrôlable car vous avez besoin d'un index partiel séparé pour chaque combinaison de colonnes nullables, de sorte que le nombre augmente de manière binomiale. Pour plusieurs colonnes nullables , voyez plutôt :

  • Pourquoi ma contrainte UNIQUE ne se déclenche-t-elle pas ?

A part :je conseille de ne pas utiliser d'identifiants à casse mixte dans PostgreSQL.