Puis-je ajouter une contrainte UNIQUE à une table PostgreSQL après sa création?


185

J'ai le tableau suivant:

 tickername | tickerbbname  | tickertype
------------+---------------+------------
 USDZAR     | USDZAR Curncy | C
 EURCZK     | EURCZK Curncy | C
 EURPLN     | EURPLN Curncy | C
 USDBRL     | USDBRL Curncy | C
 USDTRY     | USDTRY Curncy | C
 EURHUF     | EURHUF Curncy | C
 USDRUB     | USDRUB Curncy | C

Je ne veux pas qu'il y ait plus d'une colonne pour une tickername/ tickerbbnamepaire donnée . J'ai déjà créé le tableau et contient beaucoup de données (dont je me suis déjà assuré qu'il répond aux critères uniques). À mesure qu'il s'agrandit, cependant, il y a de la place pour l'erreur.

Existe-t-il un moyen d'ajouter une UNIQUEcontrainte à ce stade?


Réponses:


363

psqll'aide en ligne de:

\h ALTER TABLE

Également documenté dans la documentation postgres (une excellente ressource, et aussi facile à lire).

ALTER TABLE tablename ADD CONSTRAINT constraintname UNIQUE (columns);

6
merci @hhaamu. Oui, j'ai essayé la documentation, mais celle ci-dessus est beaucoup plus concise.
Thomas Browne

117
Si vous souhaitez laisser PostgreSQL générer le nom de l'index, utilisez ALTER TABLE tablename ADD UNIQUE (columns);. (Notez que le CONSTRAINTmot - clé doit être omis.)
jpmc26

5
J'avais besoin d'une réponse à cette question et j'ai commencé à rechercher les documents sur Google. Au lieu de la documentation Postgres, j'ai rencontré ce sujet à StackOverflow. Donc, bien qu'il soit judicieux de faire référence aux documents officiels, il est également très bon de donner la réponse pour les visites futures. Merci pour ça.
Leonard

@ jpmc26 «Si vous voulez laisser PostgreSQL générer le nom de l'index» Vous voulez dire le nom de la contrainte?
tuxayo

4
@tuxayo, une contrainte-unique est implémentée via un index dans Postgres (pour ne pas être pédant).
Chris W.

36

Oui, vous pouvez. Mais si vous avez des entrées non uniques sur votre table, cela échouera. Voici comment ajouter une contrainte unique sur votre table. Si vous utilisez PostgreSQL 9.x, vous pouvez suivre les instructions ci-dessous.

CREATE UNIQUE INDEX constraint_name ON table_name (columns);

3
Merci Zeck - belle réponse 2 ans plus tard mais apprécie toujours que les gens prennent encore le temps! Tom
Thomas Browne

1
Ce n'est pas correct. Dans les derniers Postgres, cela conduit également au message du type "Key (uuid) = (3a533772-07ac-4e76-b577-27a3878e2222) est dupliqué. La requête a échoué" si vous avez une valeur qui n'est pas unique ...
Strinder

3
@Strinder, en quoi n'est-ce pas une bonne chose? corrigez d'abord les données dupliquées.
Jasen

3
@Jasen C'est tout à fait clair. Je voulais juste souligner que la réponse "Mais si vous avez des entrées non uniques sur votre table. Voici comment ajouter une contrainte unique sur votre table." ne fonctionnera pas. Les entrées non uniques doivent bien entendu toujours être consolidées au préalable.
Strinder

A modifié la réponse pour plus de clarté
Xavier Ho

6

Si vous aviez une table qui avait déjà une contrainte existante basée sur disons: nom et nom et que vous vouliez ajouter une autre contrainte unique, vous deviez supprimer la contrainte entière de:

ALTER TABLE your_table DROP CONSTRAINT constraint_name;

Assurez-vous que la nouvelle contrainte que vous vouliez ajouter est unique / non nulle (si son Microsoft SQL, elle ne peut contenir qu'une seule valeur nulle) sur toutes les données de cette table, puis vous pouvez la recréer.

ALTER TABLE table_name
ADD CONSTRAINT constraint_name UNIQUE (column1, column2, ... column_n);

5

Oui, vous pouvez ajouter une contrainte UNIQUE après coup. Cependant, si vous avez des entrées non uniques dans votre table, Postgres s'en plaindra jusqu'à ce que vous les corrigiez.


7
select <column> from <table> group by 1 having count(*) > 1;donnera un rapport sur les valeurs dupliquées.
Jasen
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.