web-dev-qa-db-fra.com

Postgresql: contrainte conditionnellement unique

Je voudrais ajouter une contrainte qui impose l'unicité sur une colonne uniquement dans une partie d'une table.

ALTER TABLE stop ADD CONSTRAINT myc UNIQUE (col_a) WHERE (col_b is null);

La partie WHERE ci-dessus est un vœu pieux.

Une façon de faire ça? Ou devrais-je revenir à la planche à dessin relationnelle?

83
EoghanM

PostgreSQL ne définit pas de contrainte partielle (ie conditionnelle) UNIQUE - cependant, vous pouvez créer un unique partiel index . PostgreSQL utilise des index uniques pour implémenter des contraintes uniques, donc l'effet est le même, vous ne verrez simplement pas la contrainte répertoriée dans information_schema.

CREATE UNIQUE INDEX stop_myc ON stop (col_a) WHERE (col_b is null);

Voir index partiels .

140
Craig Ringer

il a déjà été dit que PG ne définit pas de contrainte UNIQUE partielle (c'est-à-dire conditionnelle). La documentation indique également que la manière préférée d'ajouter une contrainte unique à une table est ADD CONSTRAINTIndex uniques

La méthode préférée pour ajouter une contrainte unique à une table est ALTER TABLE ... ADD CONSTRAINT. L'utilisation d'index pour appliquer des contraintes uniques pourrait être considérée comme un détail d'implémentation auquel il ne faut pas accéder directement. Il faut cependant savoir qu'il n'est pas nécessaire de créer manuellement des index sur des colonnes uniques; cela ne ferait que dupliquer l'index créé automatiquement.

Il existe un moyen de l'implémenter en utilisant Contraintes d'exclusion , (merci @dukelion pour cette solution)

Dans votre cas, cela ressemblera à

ALTER TABLE stop
    ADD CONSTRAINT stop_col_a_key_part EXCLUDE (col_a WITH =) WHERE (col_b IS null);
20
Peter Yeremenko