数据库自增 ID 跳过原因探究:为什么我的自增 ID 会“跳号”?

我上周听说你谈到了数据库ID跳转。
真的很烦人。

主要原因是事务回滚。
2 02 3 年8 月我在朋友的项目中遇到了这个。
使用InnoDB引擎,自增ID存储在内存中。
事务 A 被分配 ID=1 00。
后来又被重置了。
那么ID=1 00就没用了。
下次直接使用ID=1 01 我刚刚跳了起来。

还有其他几个原因。
如果批量插入失败也会跳转。
例如,十条数据中的第五条违反了唯一键,整个批次被重置。
那么之前的1 到5 点就失效了。
即使异常重启,系统也会跳转。
未保存的 ID 将丢失。
多主复制环境肯定会实现飞跃。
当不同的节点彼此分离时,合并就会导致混乱。

解决方案取决于具体情况。

优化交易设计很好。
降低隔离级别。
例如,使用已提交读。
必须保证原子性。
不要做一半成功一半失败的事情。
缩小经营范围。
不要添加不必要的任务。

处理批量操作时要小心。
分批提交。
每个堆栈独立处理错误。
使用 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE。
这样,错误的就会被跳过,而不会影响整个堆栈。

系统级别的优化也是可能的。
分布式环境调整自增步长。
示例:节点1 使用1 ,节点2 使用2 避免冲突。
或者只使用全局 ID 生成器。
UUID、雪花算法或者数据库自带的SEQUENCE。

还必须进行监控和警报。
监控 ID 使用情况。
MySQL的innodb_autoinc_lock_mode可以定制。
Oracle的SEQUENCE可以设置为CACHE。

最后一个问题。
您的场景需要跳跃吗?如果公司仅根据 ID 是唯一的,那不是问题。
订单号、用户 ID 之类的。
跳起来就没事了。
如果你想反映订单。
发票号码。
必须避免跳号。

网上选号怎么编号的

在线拨号的规则取决于机构。

基本号码: 连续编号,例如从 0001 开始,例如注册号。
日期+序列号,例如2 3 08 01 001 ,年月日+数字。
业务前缀,例如XH-2 02 3 -0001 ,XH代表拨号。
段号,如上海A·1 2 3 B、区号。
时间分段,上午段为AM3 001 -3 5 00,下午段为PM4 001 开始。

特殊号码: 校验位,在末尾添加验证码,例如6 2 5 8 3 Luhn算法,银行卡号最后一位。
智能组合、生日组合、哈希加密、功能码植入。

实用策略: 独立编号、混合字母数字,例如 ABC1 2 3 段数预留,6 6 6 、8 8 8 段招标。
禁止组合。
不允许使用淫秽的字母组合。

动态调整: 号码池每周轮换并释放新的号码段。
冷热数字平衡,3 个月无需再循环。
概率检验,稀有数字有0.1 %的概率出现。

技术实现: 分布式ID生成器,雪花算法。
Redis缓存,预先生成1 000个数字。
防复制机制,MySQL唯一索引+乐观锁。

电信手机号码,4 .-7 空间属于7 5 5 深圳。
第八位数字区分运营商,8 是中国移动,9 是中国联通。
最后 4 位数字是随机的,但不包括 4 个连续的数字。

以具体平台公布的《选号编码规范》为准。