PostgreSQL Identity Columns
PostgreSQL identity columns are used to define a column that can automatically generate unique values.
In PostgreSQL, an identity column is a special generated column that is automatically generated and unique. An identity column is a constraint defined on the column.
Identity columns are similar with SERIAL
, they are implemented internally using SEQUENCE
.
Unlike primary keys, multiple identity columns are allowed in a table, and duplicate values are allowed in a identity column.
Syntax for Identity Columns
To create an identity column, use the following syntax:
col_name data_type
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]
explain:
-
The data type of the identity column can be:
SMALLINT
,INT
, orBIGINT
. -
The value of the
GENERATED ALWAYS AS IDENTITY
column cannot be written. Inserting or updating a value into this column will causes an error. There is a special case where a value can be inserted into this column using theOVERRIDING SYSTEM VALUE
directive in theINSERT
statement. -
The value of the
GENERATED BY DEFAULT AS IDENTITY
column can be written, including inserts and updates. -
The
sequence_options
specifies the option to the sequence used inside of by identify column. It is optional, if not specified, PostgreSQL uses the default option to generate a sequence.
You can define an identity column when creating a table with the CREATE TABLE
statement, or add an identity column with the ALTER TABLE
statement.
Define the identity column when creating the table
To add an identity column when creating a table, use the following syntax:
CREATE TABLE table_name (
column_definition,
...
col_name data_type GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ],
...
);
Add identity column
To add an identity column after the table was created, use the ALTER TABLE
statement:
ALTER TABLE table_name
ADD COLUMN col_name data_type
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ];
Set a column to the table identity column
To set an existing column as an identity column, use the ALTER TABLE
statement:
ALTER TABLE table_name
ALTER COLUMN col_name
ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ];
or
ALTER TABLE table_name
ALTER COLUMN col_name
SET GENERATED { ALWAYS | BY DEFAULT };
Unset an identity column
To suppress an identity column, use the ALTER TABLE
statement:
ALTER TABLE table_name
ALTER COLUMN col_name
DROP IDENTITY [ IF EXISTS ];
PostgreSQL identity columns Examples
Below are some examples showing the usage of PostgreSQL identity columns.
Example of creating an identity column
Use the following statement to create a table where the id
column is a identity column:
CREATE TABLE test_identity (
id INTEGER GENERATED ALWAYS AS IDENTITY,
txt VARCHAR(45) NOT NULL
);
You can view the status of the identity column in test_identity
with the \d
command:
\d test_identity
Table "public.test_identity"
Column | Type | Collation | Nullable | Default
--------+-----------------------+-----------+----------+------------------------------
id | integer | | not null | generated always as identity
txt | character varying(45) | | not null |
Insert 2 rows of test data using the following statement:
INSERT INTO test_identity (txt)
VALUES ('Apple'), ('Peach');
Find all rows in the test_identity
table:
SELECT * FROM test_identity;
id | txt
----+-------
1 | Apple
2 | Peach
(2 rows)
As you can see from the output, the auto-generated values in the id
column are an auto-incrementing sequence.
Insert a value instance into an identity column
The following INSERT
statement attempts to insert a value into the identity column:
INSERT INTO test_identity (id, txt)
VALUES (1, 'Banana')
RETURNING *;
ERROR: cannot insert into column "id"
DETAIL: Column "id" is an identity column defined as GENERATED ALWAYS.
HINT: Use OVERRIDING SYSTEM VALUE to override.
Here, the value cannot be inserted directly because the id
column has a constraint: GENERATED ALWAYS AS IDENTITY
. According to PostgreSQL’s prompt, you can use OVERRIDING SYSTEM VALUE
force to insert, as follows:
INSERT INTO test_identity (id, txt)
OVERRIDING SYSTEM VALUE
VALUES (1, 'Banana')
RETURNING *;
id | txt
----+--------
1 | Banana
(1 row)
At the same time, we can also see that the identity column allows duplicate values.
Example of multiple identity columns
There can be multiple identity columns in a table. The following statement adds an identity column id_2
with a starting value of 10 and increments by 10 each time:
ALTER TABLE test_identity
ADD COLUMN id_2 INTEGER GENERATED ALWAYS AS IDENTITY
(START WITH 10 INCREMENT BY 10);
Let’s look at the data in the table:
SELECT * FROM test_identity;
id | txt | id_2
----+--------+------
1 | Apple | 10
2 | Peach | 20
1 | Banana | 30
(3 rows)
You can find that after adding an identity column, the value in the identity column in the existing row has been automatically generated.
Insert 2 rows of test data using the following statement:
INSERT INTO test_identity (txt)
VALUES ('Pear'), ('Cherry')
RETURNING *;
id | txt | id_2
----+--------+-----
3 | Pear | 40
4 | Cherry | 50
(2 rows)
Conclusion
In this article, we learned the usage of PostgreSQL identity columns.