一个基于mysql的唯一ID生成算法

文章讨论了在MySQL环境下如何生成业务唯一的ID,提出了使用`ONDUPLICATEKEYUPDATE`语法的解决方案,并指出了这种方式在分库分表场景下的局限性,推荐了Redis和雪花算法作为替代方案,特别是利用Redisson的RAtomicLong类实现全局唯一ID。

基于数据库生成唯一ID有很多手段:oracle有funcNextval等函数,也可以用自增列。
前者依赖于oracle,后者不通用,一张表只能生成一种业务的唯一ID。
我们考虑mysql下的通用写法,要满足的能力如下:

public List<Long> genUniqueIntIds(String category, int num);

其中,category参数代表一种业务类别,num是该次生成唯一ID的个数。

记录唯一ID的数据库表结构如下:

CREATE TABLE  `t_idgen` (
    `SEQ_NAME` varchar NOT NULL COMMENT '业务类别',
    `CURRENT_VAL` bigint NOT NULL COMMENT '当前值',
    PRIMARY KEY (`SEQ_NAME`)
    )

google了一把,生成唯一ID的SQL可以这么写:

INSERT INTO t_idgen(SEQ_NAME, CURRENT_VAL)
                (SELECT #{sequenceName}, @count := #{num})
        ON DUPLICATE KEY UPDATE CURRENT_VAL = (SELECT @count := CURRENT_VAL + #{num});
        select @count;

这个写法很巧妙,使用了mysql的ON DUPLICATE KEY UPDATE的语法,首次insert,后续每次都是在当前值的基础上update。
当然,使用数据库生成唯一ID的方式是有缺陷的,它只适用于单库单表,如果分库分表,就做不到全系统唯一,可考虑使用redis或雪花算法了。
顺带说一下,基于redis实现全局唯一ID是很容易的,用redisson库的RAtomicLong类即可,而且还可以带超时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值