ADD PRIMARY KEY assigns a unique, non-null identifier to each row of a PostgreSQL table.
Step-by-step instructions for creating or altering tables so that every row is uniquely identified.
Use ALTER TABLE ... ADD PRIMARY KEY
. PostgreSQL builds a unique index in one transaction, locking the table only while the index is created.
Two forms exist: add an unnamed primary key directly, or add a named constraint with ADD CONSTRAINT ... PRIMARY KEY
. Both accept column lists and the USING INDEX
clause.
Define the key inline (id SERIAL PRIMARY KEY
) or as a table-level constraint (PRIMARY KEY (id)
) when running CREATE TABLE
.
Supply multiple comma-separated columns in the constraint: ALTER TABLE sales ADD PRIMARY KEY (order_id, product_id);
Yes. Pass its name to USING INDEX
to avoid rebuilding: ALTER TABLE users ADD CONSTRAINT users_pkey PRIMARY KEY USING INDEX users_email_key;
Verify columns are NOT NULL
, ensure no duplicate values, add keys early in design, and prefer surrogate keys when natural keys are wide.
-- Add an unnamed primary key
ALTER TABLE table_name ADD PRIMARY KEY (column [, ...]);
-- Add a named primary-key constraint
ALTER TABLE table_name
ADD CONSTRAINT constraint_name PRIMARY KEY (column [, ...])
[USING INDEX existing_unique_index];
-- 1. Make sure column is NOT NULL
ALTER TABLE public.customer ALTER COLUMN customer_id SET NOT NULL;
-- 2. Add the primary key
ALTER TABLE public.customer
ADD CONSTRAINT customer_pkey PRIMARY KEY (customer_id);
PostgreSQL raises ERROR: could not create unique index
. Run SELECT col, COUNT(*) FROM tbl GROUP BY col HAVING COUNT(*) > 1;
to locate duplicates, de-duplicate, then retry.
Primary keys implicitly require NOT NULL
. Set the column accordingly before adding the key: ALTER TABLE ... ALTER COLUMN col SET NOT NULL;
PostgreSQL must acquire an exclusive lock while creating the unique index. On large tables this can be noticeable. Consider creating a unique index concurrently first, then attach it with USING INDEX to minimize downtime.
Yes. Provide its name in the USING INDEX clause to promote it without rebuilding.
The backing unique index is dropped unless it was created separately and referenced with USING INDEX.