九月 12, 2023
摘要:在本教程中,您将学习如何使用GENERATED AS IDENTITY
约束为表创建标识列。
目录
PostgreSQL 标识列简介
PostgreSQL 版本 10 引入了一个新的约束GENERATED AS IDENTITY
,允许您自动为列分配唯一的编号。
GENERATED AS IDENTITY
约束是旧的SERIAL
列符合 SQL 标准的变体。
下面说明了GENERATED AS IDENTITY
约束的语法:
column_name type GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY[ ( sequence_option ) ]
在这个语法中:
- 类型可以是
SMALLINT
、INT
或BIGINT
。 GENERATED ALWAYS
指示 PostgreSQL 始终为标识列生成一个值。如果您尝试向GENERATED ALWAYS AS IDENTITY
列中插入(或更新)值,PostgreSQL 将发出错误。GENERATED BY DEFAULT
也指示 PostgreSQL 为标识列生成一个值。但是,如果您为插入或更新提供一个值,PostgreSQL 将使用该值插入到标识列中,而不是使用系统生成的值。
PostgreSQL 允许一张表拥有多个标识列。与SERIAL
一样,GENERATED AS IDENTITY
约束也在内部使用SEQUENCE
对象。
PostgreSQL 标识列示例
A) GENERATED ALWAYS 例子
首先,创建一个表,名为color
,以color_id
为标识列:
CREATE TABLE color (
color_id INT GENERATED ALWAYS AS IDENTITY,
color_name VARCHAR NOT NULL
);
其次,向color
表中插入新行:
INSERT INTO color(color_name)
VALUES ('Red');
由于color_id
列具有GENERATED AS IDENTITY
约束,PostgreSQL 会为其生成一个值,如下面的查询所示:
SELECT * FROM color;
第三,通过为color_id
和color_name
列提供值来插入新行:
INSERT INTO color (color_id, color_name)
VALUES (2, 'Green');
PostgreSQL 发出以下错误:
ERROR: cannot insert into column "color_id"
DETAIL: Column "color_id" is an identity column defined as GENERATED ALWAYS.
HINT: Use OVERRIDING SYSTEM VALUE to override.
要修复该错误,您可以使用OVERRIDING SYSTEM VALUE
子句,如下:
INSERT INTO color (color_id, color_name)
OVERRIDING SYSTEM VALUE
VALUES(2, 'Green');
或者改用GENERATED BY DEFAULT AS IDENTITY
。
B) GENERATED BY DEFAULT AS IDENTITY 例子
首先,删除 color
表并重新创建它。这次我们改用GENERATED BY DEFAULT AS IDENTITY
:
DROP TABLE color;
CREATE TABLE color (
color_id INT GENERATED BY DEFAULT AS IDENTITY,
color_name VARCHAR NOT NULL
);
其次,向color
表中插入一行:
INSERT INTO color (color_name)
VALUES ('White');
它按预期工作。
第三,插入另一行,其中包含color_id
列的值:
INSERT INTO color (color_id, color_name)
VALUES (2, 'Yellow');
与前面使用GENERATED ALWAYS AS IDENTITY
约束的示例不同,上面的语句工作得很好。
C) 序列选项示例
由于GENERATED AS IDENTITY
约束使用SEQUENCE
对象,因此您可以为系统生成的值指定序列选项。
例如,您可以指定起始值和增量,如下所示:
DROP TABLE color;
CREATE TABLE color (
color_id INT GENERATED BY DEFAULT AS IDENTITY
(START WITH 10 INCREMENT BY 10),
color_name VARCHAR NOT NULL
);
在此示例中,系统生成的color_id
列值从 10 开始,增量值也是 10。
首先,在color
表中插入一个新行:
INSERT INTO color (color_name)
VALUES ('Orange');
color_id
列的起始值为 10,如下所示:
SELECT * FROM color;
其次,在color
表中插入另一行:
INSERT INTO color (color_name)
VALUES ('Purple');
由于增量选项,第二行的color_id
值为 20。
SELECT * FROM color;
向现有表添加标识列
您可以使用以下形式的ALTER TABLE
语句向现有表添加标识列:
ALTER TABLE table_name
ALTER COLUMN column_name
ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY { ( sequence_option ) }
让我们看下面的例子。
首先,创建一个名为shape
的新表:
CREATE TABLE shape (
shape_id INT NOT NULL,
shape_name VARCHAR NOT NULL
);
其次,将该shape_id
列更改为标识列:
ALTER TABLE shape
ALTER COLUMN shape_id ADD GENERATED ALWAYS AS IDENTITY;
请注意,shape_id
需要有NOT NULL
约束,以便可以将其更改为标识列。否则,您将收到如下错误:
ERROR: column "shape_id" of relation "shape" must be declared NOT NULL before identity can be added
SQL state: 55000
以下命令在psql
工具中描述了shape
表:
\d shape
它返回以下输出,这正是我们所期望的:
更改标识列
您可以使用以下ALTER TABLE
语句更改现有标识列的特征:
ALTER TABLE table_name
ALTER COLUMN column_name
{ SET GENERATED { ALWAYS| BY DEFAULT } |
SET sequence_option | RESTART [ [ WITH ] restart ] }
例如,以下语句将shape
表的shape_id
列更改为GENERATED BY DEFAULT
:
ALTER TABLE shape
ALTER COLUMN shape_id SET GENERATED BY DEFAULT;
以下命令在psql
工具中描述了shape
表的结构:
\d shape
从输出中可以看到,shape_id
列从GENERATED ALWAYS
更改为了GENERATED BY DEFAULT
。
删除 GENERATED AS IDENTITY 约束
以下语句从现有表中删除GENERATED AS IDENTITY
约束:
ALTER TABLE table_name
ALTER COLUMN column_name
DROP IDENTITY [ IF EXISTS ]
例如,您可以从shape
表的shape_id
列中删除GENERATED AS IDENTITY
约束列,如下所示:
ALTER TABLE shape
ALTER COLUMN shape_id
DROP IDENTITY IF EXISTS;
在本教程中,您学习了如何使用 PostgreSQL 标识列以及如何使用GENERATED AS IDENTITY
约束来管理它。