Hologres自增序列Serial使用简介
文章目录
- 一、基础说明
- 1、简要介绍
- 2、参数说明
- 3、使用限制
- 二、举例说明
- 1、创建表插入数据
- 2、查询获取Sequence
- 3、修改自增序列的起始值
- 4、更新操作会消耗一个序列值
一、基础说明
1、简要介绍
实时数仓Hologres兼容Postgres生态,支持在建表时将字段的类型定义为Serial和Bigserial来定义自增的字段。 Serial表示INT4类型的自增字段,Bigserial表示INT8类型的自增字段。
2、参数说明
参数 | 说明 | 存储大小 | 取值范围 |
---|---|---|---|
Serial | INT4类型的自增字段 | 4字节 | -2147483648~2147483647 |
Bigserial | INT8类型的自增字段 | 8字节 | -9223372036854775808~9223372036854775807 |
3、使用限制
1、Hologres不能指定Serial和Bigserial的额外参数,包括递增步长及初始值参数,递增步长为1,初始值默认设置为1。
2、Hologres暂不支持Smallserial类型的数据。
3、首次创建Serial和Bigserial类型的表,需要Superuser在当前DB创建。然后其余用户就能按照业务逻辑创建有关Serial和Bigserial类型的表。创建Serial和Bigserial类型的表是DB级别的,如果切换数据库,Superuser需要再次执行该操作。
4、在Flink或者数据集成写入场景,仅Flink的JDBC模式和数据集成insert into模式支持写入Serial和Bigserial类型,DataHub暂不支持写入。
5、对于基于主键的insert on conflict写入场景,Serial类型不会严格保证字段的连续性增长,如需严格保序,请手动设置Serial的起始值。
6、Serial写入会有额外锁的开销,不建议单条写入时增加Serial类型,对写入性能有降低,可以攒批写入。同时如果SQL符合Fixed Plan特征,可以开启如下GUC参数,使Serial字段可以走Fixed Plan实现更高的写入性能。
--数据库级别开启GUC, 支持含有Serial类型列的Fixed Plan写入
alter database <user_db> set hg_experimental_enable_fixed_dispatcher_autofill_series=on;
7、仅Hologres V0.10及以上版本支持修改Serial参数,且仅支持restart with参数的修改。
8、Serial写入会有额外全局锁的开销,对写入性能影响较大,在性能敏感场景谨慎使用。
二、举例说明
1、创建表插入数据
DROP TABLE IF EXISTS serial_table;CREATE TABLE serial_table (id bigint,row_id serial, -- nextval('serial_table_row_id_seq'::regclass)name TEXT ,PRIMARY KEY (id)
);INSERT INTO serial_table (id, name)VALUES (1, '张三')
RETURNINGid;INSERT INTO serial_table (id, name)VALUES (2, '李四')
RETURNINGid;SELECT * FROM serial_table;
2、查询获取Sequence
SELECTtable_name,column_name,column_default
FROMinformation_schema.columns
WHEREtable_schema = 'public'AND table_name = 'serial_table'AND column_name = 'row_id';
3、修改自增序列的起始值
alter sequence serial_table_row_id_seq restart with 100; -- 修改起始值
INSERT INTO serial_table (id,name) values(3,'李四') RETURNING id; --插入数据验证
SELECT * FROM serial_table ;--查询看结果
4、更新操作会消耗一个序列值
INSERT INTO serial_table (id, name)VALUES (2, '更新ID为2的数据')
ON CONFLICT (id)DO UPDATE SETname = excluded.name;
更新时同时更新序列字段就不会占用序列值了
INSERT INTO serial_table (id,row_id, name)VALUES (4,4, '更新ID为4的数据')
ON CONFLICT (id)DO UPDATE SETname = excluded.name, row_id=excluded.row_id;