Summary: in this tutorial, you’ll learn how to use the PostgreSQL unique index to ensure the values in one or more table columns are unique.
PostgreSQL Unique Index Overview #
A unique index ensures values in one or more columns are unique across all rows in a table, maintaining the integrity of your data.
You’ll encounter an error if you attempt to insert a value already in a column with a unique index.
To create a unique index, you use the CREATE UNIQUE INDEX statement:
CREATE UNIQUE INDEX [index_name]
ON table_name (column1[, column2, ...])
[ NULLS [ NOT ] DISTINCT ];Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)In this syntax:
- First, specify the index name after the
CREATE UNIQUE INDEXkeywords. If you omit it, PostgreSQL will automatically generate a name. - Second, provide the table name on which you want to create the index.
- Third, list one or more columns included in the index.
- Third, the
NULL NOT DISTINCTtreats NULLs equally, while theNULLS DISTINCTconsiders NULLs as distinct values. The default isNULLS DISTINCT, meaning the index column may contain multiple NULLs.
PostgreSQL Unique Index Example #
First, create a table warehouse_workers to store the warehouse worker data:
CREATE TABLE IF NOT EXISTS warehouse_workers (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255),
phone VARCHAR(25),
extension VARCHAR(25)
);Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)Second, create a unique index for the email column:
CREATE UNIQUE INDEX ON warehouse_workers (email);Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)This unique index ensures the uniqueness of values in the email column of the table.
Third, insert a new row into the warehouse_workers table:
INSERT INTO
warehouse_workers (name, email, phone, extension)
VALUES
(
'Emma Smith',
'[email protected]',
'(408)-111-2222',
'101'
);Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)Finally, attempt to insert a new row with the same email address:
INSERT INTO
warehouse_workers (name, email, phone, extension)
VALUES
(
'Emma Scott',
'[email protected]',
'(408)-111-2222',
'102'
);Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)PostgreSQL issued an error:
ERROR: duplicate key value violates unique constraint "warehouse_workers_email_idx"
DETAIL: Key (email)=([email protected]) already exists.Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)The unique index warehouse_workers_email_idx does not allow duplicate emails in the email column.
Creating a unique index on multiple columns #
First, create a unique index that includes the phone and extension columns:
CREATE UNIQUE INDEX ON warehouse_workers (phone, extension);Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)Second, insert a new row into the warehouse_workers table:
INSERT INTO
warehouse_workers (name, email, phone, extension)
VALUES
(
'Mary Scott',
'[email protected]',
'(408)-111-2222',
'102'
);Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)Even though the phone number of Mary is the same as Emma’s, the statement successfully inserted a row into the table.
The reason is that the new unique index enforces the unique values in the phone and extension columns.
Third, attempt to insert a new row with the same phone and extension:
INSERT INTO
warehouse_workers (name, email, phone, extension)
VALUES
(
'Ava Garcia ',
'[email protected]',
'(408)-111-2222',
'102'
);Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)PostgreSQL issued the following error:
ERROR: duplicate key value violates unique constraint "warehouse_workers_phone_extension_idx"
DETAIL: Key (phone, extension)=((408)-111-2222, 102) already exists.Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)The reason is that the pair of values (408)-111-2222, 102) already exists in the warehouse_workers table.
Unique index vs. primary key #
In PostgreSQL, a primary key is a special kind of unique index that:
- Does not allow NULLs.
- Can be applied to one or more columns per table.
- Implies uniqueness inherently
In contrast, a unique index allows NULLs unless you specify NULL NOT DISTINCT option.
Unique index vs. unique constraint #
Both unique index and unique constraint ensure the uniqueness of values in one or more columns within a table.
However, a unique constraint is a logical schema rule, while a unique index is a physical structure that PostgreSQL uses to enforce the uniqueness.
PostgreSQL automatically generates a unique index when you create a unique constraint.
Summary #
- Use a unique index to enforce the uniqueness values in one or more columns.