PostgreSQL IDENTITY COLUMN 标识列
PostgreSQL 标识列用于定义一个可以自动生成唯一值的列。
在 PostgreSQL 中,标识列是一个特殊的生成列,该列的值能自动生成并且是唯一的。标识列是定义在列上的约束。
标识列和 SERIAL
类似,他们的内部都使用 SEQUENCE
实现。
不像主键,一个表中允许存在多个标识列,并且标识列中允许存在重复的值。
标识列的语法
要创建标识列,请使用以下语法:
col_name data_type
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]
解释说明:
-
标识列的数据类型可以是:
SMALLINT
,INT
,或BIGINT
。 -
GENERATED ALWAYS AS IDENTITY
列的值不能被写入。 向此列中插入(或更新)值将会导致一个错误。有一个特殊情况,就在INSERT
语句中使用OVERRIDING SYSTEM VALUE
指令可以向此列插入值。 -
GENERATED BY DEFAULT AS IDENTITY
列的值能被写入,包括插入和更新。 -
sequence_options
指明了标识列内部使用的序列的选项。它是可选的,如果不指定,PostgreSQL 使用默认值产生一个序列。
你可以在通过 CREATE TABLE
语句创建表时定义标识列,或者通过 ALTER TABLE
语句添加一个标识列。
在创建表时定义标识列
要在创建表时添加标识列,请使用如下语法:
CREATE TABLE table_name (
column_definition,
...
col_name data_type GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ],
...
);
添加标识列
要在创建表后添加一个标识列,请使用 ALTER TABLE
语句:
ALTER TABLE table_name
ADD COLUMN col_name data_type
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ];
将一个列设置表标识列
要将一个已有的列设置为标识列,请使用 ALTER TABLE
语句:
ALTER TABLE table_name
ALTER COLUMN col_name
ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ];
或者
ALTER TABLE table_name
ALTER COLUMN col_name
SET GENERATED { ALWAYS | BY DEFAULT };
取消一个标识列
要取消一个标识列,请使用 ALTER TABLE
语句:
ALTER TABLE table_name
ALTER COLUMN col_name
DROP IDENTITY [ IF EXISTS ];
PostgreSQL 标识列实例
下面有一些展示 PostgreSQL 标识列用法的实例。
创建标识列实例
使用下面的语句创建一个表,其中 id
列是标识列:
CREATE TABLE test_identity (
id INTEGER GENERATED ALWAYS AS IDENTITY,
txt VARCHAR(45) NOT NULL
);
您可以通过 \d
命令查看 test_identity
中标识列的情况:
\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 |
使用以下语句插入 2 行测试数据:
INSERT INTO test_identity (txt)
VALUES ('Apple'), ('Peach');
使用以下语句查找 test_identity
表中的所有行:
SELECT * FROM test_identity;
id | txt
----+-------
1 | Apple
2 | Peach
(2 rows)
从输出可以看到, id
列中的自动生成的值是一个自增的序列。
向标识列中插入值实例
下面的语句尝试使用 INSERT
向标识列中插入一个值:
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.
这里,由于 id
列带有 GENERATED ALWAYS AS IDENTITY
约束,因此不能直接插入值。按照 PostgreSQL 的提示,可以使用 OVERRIDING SYSTEM VALUE
强制插入,如下:
INSERT INTO test_identity (id, txt)
OVERRIDING SYSTEM VALUE
VALUES (1, 'Banana')
RETURNING *;
id | txt
----+--------
1 | Banana
(1 row)
同时,我们也可以看出,标识列是允许重复值的。
多个标识列实例
一个表中可以存在多个标识列,下面的语句添加一个标识列 id_2
,并且起始值为 10,每次自增 10:
ALTER TABLE test_identity
ADD COLUMN id_2 INTEGER GENERATED ALWAYS AS IDENTITY
(START WITH 10 INCREMENT BY 10);
让我们看一下表中的数据:
SELECT * FROM test_identity;
id | txt | id_2
----+--------+------
1 | Apple | 10
2 | Peach | 20
1 | Banana | 30
(3 rows)
您可以发现,添加一个标识列后,已有的行中的标识列中的值已经自动生成。
使用以下语句插入 2 行测试数据:
INSERT INTO test_identity (txt)
VALUES ('Pear'), ('Cherry')
RETURNING *;
id | txt | id_2
----+--------+-----
3 | Pear | 40
4 | Cherry | 50
(2 rows)
结论
在本文中,我们学习了 PostgreSQL 标识列的用法。