在mysql或mariadb下实现oracle的序列的一种思路

因为聚簇主键的原因,在mysql和mariadb中,用UUID做主键和用数值型ID做主键,性能上还是有比较大差别。在mysql或mariadb中,可以给表添加自增主键,自增主键是在数据insert表后才能获取到,很多情况下,有可能是要先获取这个自增ID(尤其是业务关联操作,父子表的关联新增等),这样就需要类似oracle中的序列sequence的功能。

以下是我的一个思路:

一、创建一个ID表:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for tb_sys_id
-- ----------------------------
DROP TABLE IF EXISTS `tb_sys_id`;
CREATE TABLE `tb_sys_id`  (
  `NEW_ID` bigint(20) NOT NULL COMMENT '最大ID',
  PRIMARY KEY (`NEW_ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

创建表后,先在这个表中新增ID为1的一行数据。

二、创建一个自定义函数:

CREATE DEFINER=`root`@`%` FUNCTION `get_next_id`(`v_id_count` int) RETURNS varchar(1000) CHARSET utf8
BEGIN
	declare v_id_list varchar(1000);
	declare	v_next_id int default 1;
	declare v_index int default 1;
	while v_index <= v_id_count do
		update tb_sys_id set new_id=new_id+1;
		select new_id into v_next_id from tb_sys_id limit 1;
		if v_id_list='' then
			set v_id_list=v_next_id;
		else
			select concat_ws(',',v_id_list,v_next_id) into v_id_list;
		end if;
		set v_index = v_index + 1;
	end while;
	return v_id_list;
END

因为ID表创建好后,已经新增了一条ID为1的数据,因此上面的函数中就只做update,省去做新增与更新的判断处理。通过这个函数可以一次获取一个或多个ID,返回是一个以逗号分割的ID字符串(一次返回的ID不要太多),比如:select get_next_id(5)

当然一个ID表,在业务复杂的系统中会存在竞争瓶颈,我们可以创建多个ID表,每个ID表针对不同的业务表,甚至是针对某个特定业务表创建一个ID表,mysql和mariadb还可以创建内存表(定时将内存表数据持久化到硬盘中),速度上我没有做过多测试。

延伸开,针对数据分表的合并采用自增ID主键冲突的问题,我们也可以用此思路,我们可以创建不同初始ID值表,比如不同的分表,比如分表1是从1~1000万,分表2的ID从1000万~2000万,以此规则。

这些仅仅是我的一个思路,如果大家有更好的思路,欢迎大家给我留言。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值