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_calledfalse

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