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 IDENTITYcolumn 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 VALUEdirective in theINSERTstatement. -
The value of the
GENERATED BY DEFAULT AS IDENTITYcolumn can be written, including inserts and updates. -
The
sequence_optionsspecifies 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.