GBase 8s 中数据类型serial与序列sequence之间的异同

GBase 8s 数据库对自增列有两种形式:serial数据类型(以及扩展的bigserial和serial8), int数据类型(以及扩展的bigint和int8)+序列组合实现。
这两种实现方式各有各的优势,以下我们以测试来说明。

创建测试表及相应的触发器、存储过程

自增数据类型serial,仅需要指明数据类型即可

-- 自增数据类型
create table tabserial (id serial, name varchar(128));

生成的实际表结构,serial会自动加上not null约束

create table "gbasedbt".tabserial 
  (
    id serial not null ,
    name varchar(128)
  );

对于使用序列方式,则需要复杂一些,同时为了对比,我们这里需要对int数据类型分别做是否非空约束限制。
允许空值

-- 不指定非空限制,允许null值
create table tabseq1 (id int, name varchar(128));

-- 表对应的触发器
create sequence tabseq1_id;

-- 触发存储过程的过程部分
create procedure tri_proc_tabseq1() referencing new as new old as old for tabseq1
  if new.id is null or new.id = 0 then
    let new.id = tabseq1_id.nextval;
  end if;
end procedure;

-- 触发存储过程的insert触发器部分
create trigger tri_tabseq1_insert insert on tabseq1
for each row (
  execute procedure tri_proc_tabseq1() with trigger references
);

-- 触发存储过程的update触发器部分
create trigger tri_tabseq1_update update on tabseq1
for each row (
  execute procedure tri_proc_tabseq1() with trigger references
);

不允许空值

-- 指定非空限制,不允许null值
create table tabseq2 (id int not null, name varchar(128));

-- 表对应的触发器
create sequence tabseq2_id;

-- 触发存储过程的过程部分
create procedure tri_proc_tabseq2() referencing new as new old as old for tabseq2
  if new.id is null or new.id = 0 then
    let new.id = tabseq2_id.nextval;
  end if;
end procedure;

-- 触发存储过程的insert触发器部分
create trigger tri_tabseq2_insert insert on tabseq2
for each row (
  execute procedure tri_proc_tabseq2() with trigger references
);

-- 触发存储过程的update触发器部分
create trigger tri_tabseq2_update update on tabseq2
for each row (
  execute procedure tri_proc_tabseq2() with trigger references
);

对比测试

1,插入测试,占位符是0

insert into tabserial values(0,'test001');
insert into tabseq1   values(0,'test001');
insert into tabseq2   values(0,'test001');

三者均可执行,结果均为

id    1
name  test001

结论1:允许使用0作为占位符

2,插入测试,占位符是null

insert into tabserial values(null,'test002');
insert into tabseq1   values(null,'test002');
insert into tabseq2   values(null,'test002');

只有tabseq1操作成功,其它两个均报非空限制错误。
表tabseq1的结果为

id    1
name  test001

id    2
name  test002

表tabserial和tabseq2的结果为

id    1
name  test001

结论2:均会受到非空限制的限制

3,插入测试,无占位符

insert into tabserial(name) values('test003');
insert into tabseq1(name)   values('test003');
insert into tabseq2(name)   values('test003');

表tabserial和tabseq1操作成功,tabseq2报非空限制错误。
表tabserail的结果为

id    1
name  test001

id    2
name  test003

表tabseq1的结果为

id    1
name  test001

id    2
name  test002

id    3
name  test003

表tabseq2的结果为

id    1
name  test001

结论3:serial数据类型在无值自动更新;使用序列时,需考虑字段的非空限制。

4,更新测试

update tabserial set id = 0 where id = 1;
update tabseq1   set id = 0 where id = 1;
update tabseq2   set id = 0 where id = 1;

表tabserial操作失败,报serial字段不允许更新;tabseq1和tabsq2操作成功
表tabserail的结果为

id    1
name  test001

id    2
name  test003

表tabseq1的结果为

id    4
name  test001

id    2
name  test002

id    3
name  test003

表tabseq2的结果为

id    2
name  test001

结论4:serial数据类型不接受更新操作

测试总结:

自增数据类型serial与序列的相同点
1,均允许使用0占位符;
2,均受非空限制;
自增数据类型serial与序列的不同点
1,serial不允许字段更新,而序列对应的字段允许
2,序列对应的字段无非空限制时,更加灵活

标签: 序列, serial, sequence

添加新评论