知识点 | 分库分表情况下全局唯一主键的一种简单实现

【引言】
大家知道,关系型数据库易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量 >1000W行或 >100G后,由于查询维度较多,即使添加从库读、优化索引,优化后性能仍下降严重。

此时就要考虑对其进行切分了,目的就在于减少数据库的负担,缩短查询时间。

在分库分表环境中,由于表中数据同时存在不同数据库中,单库主键值平时使用的自增长将不再适用,某分区数据库下自生成的ID无法保证全局唯一。因此需要单独设计全局主键,以避免跨库主键重复问题。

常见的主键生成策略有:UUID、创建主键ID表、Snowflake分布式自增ID算法。

今天就来讲一下最简单的创建主键ID表方法,此方法实现最为简单。

首先,在一台数据库中建立 sequence 表:
CREATE TABLE sequence (
id bigint(20) unsigned NOT NULL auto_increment,
stub char(1) NOT NULL default ‘’,
PRIMARY KEY (id),
UNIQUE KEY stub (stub)
) ENGINE=MyISAM;

stub字段设置为唯一索引,同一stub值在sequence表中只有一条记录,可以同时为多张表生成全局ID。

使用 MyISAM 存储引擎而非 InnoDB,目的是为了获取更高性能。
MyISAM使用的是表级别的锁,对表的读写是串行的,故不用担心在并发时两次读取同一个ID值。

当需要全局唯一的64位ID时,执行:

mysql> REPLACE INTO sequence (stub) VALUES ('a');
mysql> select * from sequence;
+----+------+
| id | stub |
+----+------+
|  1| a    |
+----+------+
1 row in set (0.00 sec)

注意:select last_insert_id() 必须与replace into在同一数据库连接下才能得到刚刚插入的新ID。

使用replace into代替insert into好处是避免了表行数过大,不需要另外定期清理。

此方案优点简单易实现,缺点也明显:存在单点问题,强依赖DB。

当DB异常时,整个分布式系统将因取不到最新的序号导致库不可用;配置主从可增加可用性,但当主库挂了,主从切换时,数据一致性在数据修改较为频繁的场景下难以保证;且,整体分布式的性能瓶颈也将受限于此产生主键ID序列的服务器读写性能上。

欢迎关注个人微信公众号:
image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值