This afternoon, I had to add a unique index for some table in the Sicirec PostgreSQL database. I had already assumed that I needed to use CREATE UNIQUE INDEX to create my new unique index until I noticed, thanks to pgAdmin‘s clear GUI, that some tables clearly had unique constraints and unique indexes while one table lacked a unique constraint and only had an unique index defined.

This motivated me to take a closer look at PostgreSQL’s documentation on unique indexes:

Note: The preferred way to add a unique constraint to a table is ALTER TABLE ... ADD CONSTRAINT. The use of indexes to enforce unique constraints could be considered an implementation detail that should not be accessed directly. One should, however, be aware that there’s no need to manually create indexes on unique columns; doing so would just duplicate the automatically-created index.

Grepping for CREATE UNIQUE INDEX in our migration history quickly revealed that the index which lacked an accompanying constraint was indeed created by CREATE UNIQUE INDEX instead of by ALTER TABLE ... ADD CONSTRAINT. So, now I know that, indeed, I have to use ALTER TABLE ... ADD CONSTRAINT instead of CREATE UNIQUE INDEX to add unique constraints with accompanying indexes to existing tables.