Greenplum数据增量导入的唯一值自增处理

简介: 阿里云的Greenplum(以下简称GP)已经公测了一段时间,陆续接到很多用户的反馈。其中一些使用上的问题比较有趣,在这里与大家分享一下。 其中一个case是字段的唯一键和自增值问题。在导入GP之前,某id字段已经保证了唯一性,但在此次导入之后,可能会有更多的导入,这个时候希望GP在原来最大id值的基础上自增。 GP是在PostgreSQL(以下简称PG)上开发而来,其操作基本沿用。在

阿里云的Greenplum(以下简称GP)已经公测了一段时间,陆续接到很多用户的反馈。其中一些使用上的问题比较有趣,在这里与大家分享一下。

其中一个case是字段的唯一键和自增值问题。在导入GP之前,某id字段已经保证了唯一性,但在此次导入之后,可能会有更多的导入,这个时候希望GP在原来最大id值的基础上自增。

GP是在PostgreSQL(以下简称PG)上开发而来,其操作基本沿用。在PG上,实现自增的方法是通过serial:

postgres=> create table tuniq(id serial, name text);
CREATE TABLE
postgres=> insert into tuniq (name) values('zero');
INSERT 0 1
postgres=> insert into tuniq (name) values('second');
INSERT 0 1
postgres=> 
postgres=> 
postgres=> select * from tuniq;
 id |  name  
----+--------
  1 | zero
  2 | second
(2 rows)

这里的serial,并不是一个数据类型,而是通过建立一个全局序列“tuniq_id_seq”(表名_字段名_seq)实现的,每次插入的时候会从这个seq中取值作为字段的默认值,从而做到自增。

那么,如果你执行下面的语句会怎么样?

postgres=> insert into tuniq (id, name) values(1, 'second');

在id没有唯一约束的情况下,这是可以执行成功的。原因是id字段并没有加任何约束,而serial只是简单的从sequence给id赋值而已。这样就带来一个问题:

postgres=> select * from tuniq;
 id |  name  
----+--------
  1 | zero
  2 | second
  1 | second
(3 rows)

如果在这个字段上有唯一约束的话,那么开始的时候导入包括id在内的数据,之后执行不包括id的插入的时候,就会去从sequence取值。而这个时候,因为sequence的当前最新值尚未更新,所以可能会出现与已导入数据冲突的情况,如:

postgres=> create table tuniq(id serial unique, name text);
CREATE TABLE
postgres=> 
postgres=> 
postgres=> insert into tuniq values(0, 'zero');
INSERT 0 1
postgres=> insert into tuniq values(1, 'first');                                                                                                                                                           INSERT 0 1
postgres=> select * from tuniq;                                                                                                                                                                             id | name  
----+-------
  0 | zero
  1 | first
(2 rows)

postgres=> insert into tuniq (name) values('second');
ERROR:  duplicate key value violates unique constraint "tuniq_id_key"
DETAIL:  Key (id)=(1) already exists.

这个问题的解决方法也很简单:

postgres=> select setval('tuniq_id_seq', max(id)) from tuniq;
 setval 
--------
      1
(1 row)

postgres=> insert into tuniq (name) values('second');
INSERT 0 1
postgres=> select * from tuniq;
 id |  name  
----+--------
  0 | zero
  1 | first
  2 | second
(3 rows)

更详细的用法和解释参考这里

那如果是开始加了唯一键约束,但没有采用serial该如何实现字段的继续递增?

正所谓:知其然,知其所以然。serial的原理,不过是从sequence取值作为字段的默认值而已。那如果想要做到类似的方式,用同样的方式做就好了。

让我们模拟一下这个场景:

postgres=> create table tuniq(id int unique, name text); 
NOTICE:  CREATE TABLE / UNIQUE will create implicit index "tuniq_id_key" for table "tuniq"
CREATE TABLE
postgres=> 
postgres=> insert into tuniq(id, name) values(0, 'zero');
INSERT 0 1
postgres=> insert into tuniq(id, name) values(1, 'first');
INSERT 0 1
postgres=> insert into tuniq(id, name) values(2, 'second');
INSERT 0 1
postgres=> 
postgres=> select * from tuniq ;
 id |  name  
----+--------
  1 | first
  0 | zero
  2 | second
(3 rows)

这个数据已经导入完成,后续想让id键自增的话,需要先建一个sequence,并更新到最新的值:

postgres=> create sequence tuniq_id_seq;
CREATE SEQUENCE
postgres=> 
postgres=> select setval('tuniq_id_seq', max(id)) from tuniq;
 setval 
--------
      2
(1 row)

postgres=> 
postgres=> ALTER TABLE tuniq  ALTER id  set default nextval('tuniq_id_seq'::regclass);
ALTER TABLE

这个时候,就可以把sequence的值作为tuniq表id字段的默认值了,如:

postgres=> insert into tuniq(name) values('third');
INSERT 0 1
postgres=> 
postgres=> 
postgres=> select * from tuniq;
 id |  name  
----+--------
  1 | first
  3 | third
  0 | zero
  2 | second
(4 rows)

从以上我们可以看出,用PG/GP的自增需要注意:

  1. serial是通过sequence设置字段的默认值
  2. 可以考虑加上唯一约束,防止主动插入该字段的值,破坏该字段值的自增序和唯一性(如果业务关心的话)
目录
相关文章
|
9月前
|
人工智能 C语言 Python
[oeasy]python051_什么样的变量名能用_标识符_identifier
本文介绍了Python中变量名的命名规则,强调标识符(identifier)必须以字母或下划线开始,后续可包含字母、下划线及数字。通过`isidentifier()`函数可验证字符串是否为合法标识符。文中还探讨了为何数字不能作为标识符的开头,并提供了相关练习与解答,最后提及这些规则源自C语言的影响。
241 69
|
Web App开发 安全 应用服务中间件
|
11月前
|
人工智能 自然语言处理 语音技术
《ModelScope:模型即服务的创新与未来》
【10月更文挑战第2天】** 本文深入探讨了 ModelScope 所代表的模型即服务(MaaS)模式的发展背景、核心特点、技术优势、应用场景以及对各个领域带来的深远影响。通过对其架构、功能和实际案例的分析,展现了 ModelScope 在推动人工智能发展、促进产业升级和创新方面的巨大潜力,同时也对其未来发展趋势进行了展望。
839 1
|
前端开发 JavaScript 算法
Github 最受欢迎的 35 个项目一览
Github 最受欢迎的 35 个项目一览
666 0
|
网络协议 Ubuntu 前端开发
如何在操作使用ufw设置防火墙
如何在操作使用ufw设置防火墙
|
SQL API 数据库
【Entity Framework】EF配置文件设置详解
【Entity Framework】EF配置文件设置详解
159 0
|
网络协议 安全 Python
Scapy一个强大的 Python 程序(二)
Scapy是Python的网络安全工具,可用于创建和修改网络包
250 1
|
弹性计算 缓存 并行计算
带你读《弹性计算技术指导及场景应用》——3. Ada Lovelace架构解读及RTX 4090性能测试分析(1)
带你读《弹性计算技术指导及场景应用》——3. Ada Lovelace架构解读及RTX 4090性能测试分析(1)
619 4
|
SQL DataWorks 监控
DataWorks产品使用合集之如何创建一个函数并使用JAR包里面的方法
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
265 3
|
供应链 搜索推荐 物联网
云上智能供应链:重塑物流与供应链管理的未来图景
云上智能供应链作为供应链管理领域的创新实践,正以其独特的优势和潜力引领着供应链管理的未来发展。通过数字化、智能化和集成化的手段,云上智能供应链不仅提升了供应链的整体效能和竞争力,还为企业带来了更多的商业价值和市场机遇。我们有理由相信,在未来的日子里,云上智能供应链将成为推动企业转型升级和实现可持续发展的重要力量。
1774 0

热门文章

最新文章