sequence 的相关操作

sequence 是 Postgres 的一种对象,用来实现自增序列的生成,一般会用来生成表的主键的值。例如下面这个 task 表的主键就使用一个 sequence task_id_seq 来生成:

testdb=# \d task
Table "public.task"
Column   |           Type           |                     Modifiers
------------+--------------------------+---------------------------------------------------
id         | integer                  | not null default nextval('task_id_seq'::regclass)

Postgres 提供了一些操作 sequence 的函数:https://www.postgresql.org/docs/9.6/functions-sequence.html。

查询 sequence 会生成的下一个值

如果当前的 session 调用过了 nextval() 函数,就可以使用 currval(seqname) 函数来获取一个 sequence 对象最后一次被 nextval() 函数返回的值,将其加一就可以得到下一个值。注意,如果在当前 session 中没有对这个 sequence 调用过 nextval() 函数,那么调用 currval(seqname) 将返回错误。

不过,即使当前的 session 没有调用对应 nextval(seqname),也可以通过直接查看 relation 的方式起来确定一个 sequence 会生成的下一个值。例如,上面的 task_id_seq:

testdb=# \d task_id_seq
         Sequence "public.task_id_seq"
    Column     |  Type   |        Value
---------------+---------+---------------------
 sequence_name | name    | task_id_seq
 last_value    | bigint  | 6296
 start_value   | bigint  | 1
 increment_by  | bigint  | 1
 max_value     | bigint  | 9223372036854775807
 min_value     | bigint  | 1
 cache_value   | bigint  | 1
 log_cnt       | bigint  | 29
 is_cycled     | boolean | f
 is_called     | boolean | t
Owned by: public.task.id

关注其中的 last_value 字段和 is_called 字段。last_value 表示上次被调用的值是多少,这个值会从 start_value 指定的值开始,一般是 1。 如果 is_called 的值为 false,表示 last_value 这个值还没有被返回过,会在下次返回。一般来说,当我们刚创建了一个表时,还未向其中插入数据,即last_value 的值等于 start_value 的值时,is_called 的值会设置为 false。

上面这个输出表示 task_id_seq 最后一次返回的是 6296,下一次返回 6297。

重置一个 sequence

常用的有两个方法。

  1. ALTER SEQUENCE seq RESTART WITH 1;,将值重置为 1。
  2. SELECT setval('sequence', 1); 设置 last_value 的值为 1。SELECT setval('sequence', 1, false); 设置 last_value 的值为 1,is_called 为 false。

知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。