(一)Sequence使用
1.函数
函数 | 返回值 | 描述 |
currval(regclass) | bigint | 返回指定序列最近获得的值 |
lastval() | bigint | 返回当前会话最近一次nextval返回的数值 |
nextval(regclass) | bigint | 前进序列并返回新值 |
setval(regclass,last_value) | bigint | 设置序列当前值 |
setval(regclass,last_value,is_called) | bigint | 设置序列当前值和is_called标志 |
参数:
Regclass : 序列函数要操作的序列由regclass参数指定,该参数只是序列在pg_class系统编目中的OID。不过,你不必手动查找OID,因为regclass数据类型的输入转换器会帮你完成这项工作。只需将序列名称用单引号括起来,使其看起来像一个字面常量。
is_called : 在定义序列或setval后是否曾调用过nextval,如果为false,那么下一次nextval将返回指定数值
函数详细解释:
2.语法
1)创建序列
CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { table.column | NONE } ]
可选子句START WITH start允许序列从任何地方开始。升序序列的默认初始值是minvalue,降序序列的默认初始值是maxvalue。
可选子句CACHE cache 指定了预分配和存储在内存中的序列号数量,以便更快地访问。最小值为1(一次只能生成一个值,即没有缓存),这也是默认值。
CYCLE选项允许在升序或降序序列分别达到maxvalue或minvalue时进行换行。如果达到了限制,下一个生成的值将分别是minvalue或maxvalue。如果指定了NO CYCLE,则在序列达到minvalue/maxvalue之后的任何调用都将返回错误。
2)修改序列
ALTER SEQUENCE name [ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ]
[ RESTART [ [ WITH ] restart ] ]
[ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { table.column | NONE } ]
ALTER SEQUENCE name OWNER TO new_owner
ALTER SEQUENCE name RENAME TO new_name
ALTER SEQUENCE name SET SCHEMA new_schem
可选子句RESTART [WITH restart]改变序列的当前值。这相当于用is_called = false调用setval函数(见函数说明):指定的值将在下一次调用nextval时返回。写RESTART时没有restart值,相当于提供由CREATE SEQUENCE记录的或ALTER SEQUENCE START WITH最后设置的start值。
可选子句START WITH start 改变记录的序列的起始值。这对当前序列的值没有影响;它只是设置未来的ALTER SEQUENCE RESTART命令将使用的值。
CACHE与CYCLE与创建序列作用一样。
3)删除序列
DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
IF EXISTS 如果不存在该序列,不抛出错误
3.自增类型
SERIAL 是一个关键字,用于定义自增的整数列。它实际上是一个特殊的数据类型,用于自动递增生成唯一标识值。
使用 SERIAL 关键字可以简化创建自增列的过程。当你在表中定义一个列为 SERIAL 类型时,PostgreSQL 会自动创建一个序列(Sequence)对象,并将该序列与该列关联起来。每次插入一行数据时,该列的值会自动递增。
下面是使用 SERIAL 关键字的语法示例:
CREATE TABLE my_table (
id SERIAL PRIMARY KEY,
name VARCHAR(50)
);
在上面的示例中,id 列被定义为 SERIAL 类型,并指定为主键。这意味着每次插入一行数据时,id 列的值会自动递增,并且保证唯一性。
SERIAL关键字分类:
1.smallserial/serial2:创建出的列类型是int2
2.serial/serial4:创建出的列类型是int
3.bigserial/serial8:创建出的列类型是int8
总结起来,SERIAL 关键字是 PostgreSQL 中用于定义自增整数列的一种简化语法。它自动创建序列并与列关联,使得插入数据时自动生成唯一标识值变得更加方便。
(二)Sequence维护
1.序列元信息
postgres=# \d g_test.id_seq;
Sequence "g_test.id_seq"
Column | Type | Value
---------------+---------+---------------------
sequence_name | name | id_seq //序列名称
last_value | bigint | 1 //当前值
start_value | bigint | 1 //起始值
increment_by | bigint | 1 //步长
max_value | bigint | 9223372036854775807 //最大值
min_value | bigint | 1 //最小值
cache_value | bigint | 1 //缓存的标识个数
log_cnt | bigint | 0 //写入日志的个数
is_cycled | boolean | f //标识是否可循环使用
is_called | boolean | f //在定义序列或setval后是否曾调用过nextval
2.实例
创建序列后做nextval操作,在Master和Segment节点上查询序列
查看Master的Sequence维护元信息
看每个Segment的Sequence维护元信息
通过Master和Segment的元信息可以看出,只有Master一直更新元信息,Segment的Sequence元信息一直不变,所以Sequence是由Master维护的。如果直连节点,对序列做nextval操作,相当于单机操作,节点上的序列的元信息会产生变化。
(三)Sequence分配机制
所有的Segment获取最新的Sequence都需要向Master发送next请求,然后Master更新Sequence元信息,返回给Segment。为了实现Sequence,Master和Segment多了一次交互。
协议:
QE->QD : QE发给QD消息类型为'A'的消息,QD可以通过查询 PQnotifies 数组来获取该通知的信息。
pq_beginmessage(&buf, 'A');
pq_sendint(&buf, srcPid, sizeof(int32));
pq_sendstring(&buf, channel);
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
pq_sendstring(&buf, payload);
pq_endmessage(&buf);
QD->QE:QD给QE发送的语句起始字节是‘?’,通过该字节判断是否为nextval操作返回的信息。
#define SEQ_NEXTVAL_QUERY_RESPONSE '?'
if (pqPutMsgStart(SEQ_NEXTVAL_QUERY_RESPONSE, false, conn) < 0)
elog(ERROR, "Failed to send sequence response: %s", PQerrorMessage(conn));
交互流程: