Postgresql 使用 Sequence(序列) 的方法

发布时间:2012-11-21 13:54:32

摘自:Posgresql 中国

4.11.1)我怎样创建一个序列号/自动递增的字段?

PostgreSQL 支持 SERIAL 数据类型。它在字段上自动创建一个序列和索引。例如:
CREATE TABLE person (   id   SERIAL,   name TEXT  );会自动转换为:
CREATE SEQUENCE person_id_seq; CREATE TABLE person (   id   INT4 NOT NULL DEFAULT nextval('person_id_seq'),  name TEXT );参考 create_sequence 手册页获取关于序列的更多信息。

4.11.2)我如何获得一个插入的序列号的值?

一种方法是在插入之前先用函数 nextval() 从序列对象里检索出下一个 SERIAL 值,然后再显式插入。使用 4.11.1 里的例表,可用伪码这样描述:
new_id = execute("SELECT nextval('person_id_seq')"); execute("INSERT INTO person (id, name) VALUES (new_id, 'Blaise Pascal')");这样还能在其他查询中使用存放在 new_id 里的新值(例如,作为 person 表的外键)。 注意自动创建的 SEQUENCE 对象的名称将会是 <table>_<serialcolumn>_seq, 这里 table 和 serialcolumn 分别是你的表的名称和你的 SERIAL 字段的名称。
类似的,在 SERIAL 对象缺省插入后你可以用函数 currval() 检索刚赋值的 SERIAL 值,例如:
execute("INSERT INTO person (name) VALUES ('Blaise Pascal')"); new_id = execute("SELECT currval('person_id_seq')");

4.11.3)使用 currval() 会导致和其他用户的冲突情况(race condition)吗?

不会。currval() 返回的是你本次会话进程所赋的值而不是所有用户的当前值。

4.11.4)为什么不在事务异常中止后重用序列号呢?为什么在序列号字段的取值中存在间断呢?

为了提高并发性,序列号在需要的时候赋予正在运行的事务,并且在事务结束之前不进行锁定, 这就会导致异常中止的事务后,序列号会出现间隔。