PostgreSQL:串行与身份

Sti*_*ers 8 postgresql

要在表上具有整数自动编号主键,可以使用 SERIAL

但是我注意到该表information_schema.columns具有许多identity_字段,实际上,您可以创建一个带有GENERATED说明符的列 ...

有什么不同?他们引入了不同的PostgreSQL版本吗?是一个比另一个更好的选择吗?

a_h*_*ame 19

serial是自动生成的唯一值的“旧”实现,多年来一直是Postgres的一部分。但是,这不是SQL标准的一部分。

为了更符合SQL标准,Postgres 10使用引入了语法generated as identity

基础实现仍然基于序列,该定义现在符合SQL标准。新语法允许的一件事是防止意外覆盖该值。

请考虑以下表格:

create table t1 (id serial primary key);
create table t2 (id integer not null generated always as identity);
Run Code Online (Sandbox Code Playgroud)

现在,当您运行时:

insert into t1 (id) values (1);
Run Code Online (Sandbox Code Playgroud)

基础序列和表中的值不再同步。如果你跑另一个

insert into t1 default_values;
Run Code Online (Sandbox Code Playgroud)

因为第一次插入时序列未推进,所以您会收到错误消息,现在尝试1再次插入该值。

在第二张桌子上

insert into t2 (id) values (1);
Run Code Online (Sandbox Code Playgroud)

结果是:

ERROR: cannot insert into column "id"
Detail: Column "id" is an identity column defined as GENERATED ALWAYS.
Run Code Online (Sandbox Code Playgroud)

因此,您可能会意外地“忘记”序列用法。您仍然可以使用以下override system value选项来强制执行此操作:

insert into t2 (id) overriding system value values (1);
Run Code Online (Sandbox Code Playgroud)

仍然会使您的序列与表中的值不同步,但至少让您意识到了这一点。


建议使用新的标识语法,而不是串行的