How do PRIMARY KEY and UNIQUE constraints differ in PostgreSQL? How do NULLs behave in a UNIQUE column?
Show the explanation
Both reject duplicates and both create a unique B-tree index automatically.
| PRIMARY KEY | UNIQUE | |
|---|---|---|
| Per table | at most one | any number |
| NULLs | not allowed (implies NOT NULL) | allowed |
| Purpose | the row's identity; target of foreign keys by default | an alternate key (email, roll number) |
create table users (
id bigint generated always as identity primary key,
email text not null unique,
phone text unique -- many rows may have a NULL phone
);By default PostgreSQL treats NULLs as distinct in a UNIQUE constraint, so many rows can have phone = NULL. Since PostgreSQL 15 you can write unique nulls not distinct (phone) to allow at most one NULL. For case-insensitive uniqueness, use an expression index: create unique index on users (lower(email));.
Original UniCircle question. Last reviewed 22 Oct 2026.
