前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >唯一主键方案之数据库维护区间分配

唯一主键方案之数据库维护区间分配

作者头像
JMCui
发布2021-08-20 10:35:15
5750
发布2021-08-20 10:35:15
举报
文章被收录于专栏:JMCuiJMCui

我们介绍一种基于数据库维护自增 ID 区间,结合内存分配的策略,这也是淘宝的 TDDL 等数据库中间件使用的主键生成策略。

使用这种方式首先在数据库中创建 sequence 表,其中的每一行,用于记录某个业务主键当前已经被占用的 ID 区间的最大值。sequence 表的主要字段是 name 和 value,其中 name 是当前业务序列的名称,value 存储已经分配出去的 ID 最大值。

代码语言:javascript
复制
CREATE TABLE `sequence_global` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Id',
  `app_name` varchar(64) NOT NULL COMMENT 'sequence name',
  `app_value` bigint(32) NOT NULL COMMENT 'sequence current value',
   `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
   PRIMARY KEY (`id`),
  UNIQUE KEY `unique_name` (`app_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

接下来插入一条行记录,当需要获取主键时,每台服务器主机从数据表中取对应的 ID 区间缓存在本地,同时更新 sequence 表中的 value 最大值记录。

现在我们新建一条记录,比如设置一条 order 更新的规则,插入一行记录如下:

代码语言:javascript
复制
INSERT INTO sequence_global(app_name,app_value,create_time,update_time) values('test',200,now(),now());

当服务器在获取主键增长区段时,首先访问对应数据库的 sequence 表,更新对应的记录,占用一个对应的区间。比如我们这里设置步长为 200,原先的 value 值为 1000,更新后的 value 就变为了 1200。

取到对应的 ID 区间后,在服务器内部进行分配,涉及的并发问题可以依赖乐观锁等机制解决。

有了对应的 ID 增长区间,在本地就可以使用 AtomicInteger 等方式进行 ID 分配。

不同的机器在相同时间内分配出去的 ID 可能不同,这种方式生成的唯一 ID,不保证严格的时间序递增,但是可以保证整体的趋势递增,在实际生产中有比较多的应用。

为了防止单点故障,sequence 表所在的数据库,通常会配置多个从库,实现高可用。

参考代码实现:https://github.com/JMCuixy/dubbo-demo/tree/master/sequence

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-08-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档