问题
在我日常使用 PostgreSQL 数据库过程中,会遇到一个问题:我在重新创建一个数据库表时,往往会导入已有的数据,这样会导致新增表数据时,由于 id 采用了自增,会从 1 开始生成,然后由于已有数据的缘故,所以会导致 id 重复报错。
解决
查看了 stackoverflow 的一些回答,发现了一个解决方案:采用 ALTER SEQUENCE
语句进行修改。
ALTER SEQUENCE
ALTER SEQUENCE — 更改序列生成器的定义
语法:
ALTER SEQUENCE [ IF EXISTS ] name
[ AS data_type ]
[ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ]
[ RESTART [ [ WITH ] restart ] ]
[ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { table_name.column_name | NONE } ]
ALTER SEQUENCE [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
ALTER SEQUENCE [ IF EXISTS ] name RENAME TO new_name
ALTER SEQUENCE [ IF EXISTS ] name SET SCHEMA new_schema
参数:
name
要变更的序列名称。
IF EXISTS
如果序列不存在,不抛出错误。(这种情况会发出通知)
data_type
可选的子句 AS data_type 改变序列的数据类型。有效的类型是 smallint、integer 和 bigint。
改变数据类型会自动改变序列的最小值和最大值,前提是以前的最小值和最大值是旧数据类型的最小值或最大值(换句话说,如果序列是用 NO MINVALUE 或 NO MAXVALUE 创建的,隐含地或明确地)。否则,最小值和最大值将被保留,除非作为同一命令的一部分给出新的值。如果最小值和最大值不适合新的数据类型,将产生一个错误。
increment
子句 INCREMENT BY increment 是可选的。一个正值将形成升序,一个负值将形成降序。如果没有指定,将保持旧的增量值。
minvalue
NO MINVALUE
可选的子句 MINVALUE minvalue 决定了一个序列可以产生的最小值。如果没有指定 MINVALUE,将分别使用默认的 1 和升序和降序的数据类型的最小值。如果两个选项都没有指定,将保持当前的最小值。
maxvalue
NO MAXVALUE
可选的子句 MAXVALUE maxvalue 决定了序列的最大值。如果没有指定 MAXVALUE,将分别使用数据类型的最大值和升序和降序的 -1 的默认值。如果两个选项都没有指定,将保持当前的最大值。
start
可选的子句 START WITH start 改变序列的记录起始值。这对当前的序列值没有影响;它只是设置了未来 ALTER SEQUENCE RESTART 命令将使用的值。
restart
可选子句 RESTART [ WITH restart ] 改变序列的当前值。这与调用 is_called = false 的 setval 函数类似:指定的值将由下次调用 nextval 返回。写入没有重启值的 RESTART 等同于提供由 CREATE SEQUENCE 记录的或由 ALTER SEQUENCE START WITH 最后设置的起始值。
与 setval 调用相反,序列上的 RESTART 操作是事务性的,并阻止并发的事务从同一序列中获取数字。如果这不是想要的操作模式,应该使用 setval。
cache
条款 CACHE 缓存使序列号被预先分配并存储在内存中,以加快访问速度。最小值为 1(一次只能生成一个值,即没有缓存)。如果没有指定,将保持旧的缓存值。
CYCLE
可选的 CYCLE 关键词可以用来使序列在升序或降序分别达到最大值或最小值时进行环绕。如果达到极限,下一个生成的数字将分别是最小值或最大值。
NO CYCLE
如果指定了可选的 NO CYCLE 关键字,在序列达到最大值后对 nextval 的任何调用将返回一个错误。如果没有指定 CYCLE 或 NO CYCLE,将保持旧的循环行为。
OWNED BY table_name.column_name
OWNED BY NONE
OWNED BY 选项使序列与一个特定的表列相关联,这样,如果该列(或其整个表)被丢弃,序列也将被自动丢弃。如果指定了这个选项,这个关联将取代以前为序列指定的任何关联。指定的表必须有相同的所有者,并且与序列在同一模式下。指定 OWNED BY NONE 会删除任何现有的关联,使序列成为 "独立的"。
new_owner
序列的新所有者的用户名。
new_name
序列的新名称。
new_schema
序列的新 schema。
例子
ALTER SEQUENCE pages_id_seq RESTART with 14688;
pages 新的序列自增 id 将从 14688 开始