为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【概述】 场景 + 问题概述
新增数据时报错大意是返回的新ID数值太大了,long类型放不下.
【应用框架及开发适配业务逻辑】
mybatis-plus3. 单表新增操作, 主键设为auto_random , 实体类主键标注:
@TableId(value = "pasting_id", type = IdType.AUTO)
private Long pastingId;
该类型会自动获取新增后返回的ID并设置到对应属性, insert操作后报错,返回的id长度有20多位了,long类型放不下
【TiDB 版本】 8.5.3
另外这个ID限制实在不方便,传统数据库都是顺序id更有效, 迁移数据时非常不方便
酒余尚温
5
在 TiDB 8.5.3 中,AUTO_INCREMENT + AUTO_ID_CACHE 的自增 ID 表现和传统 MySQL 有明显差异。
这是因为 TiDB 使用的是 分布式全局唯一 ID 分配机制(AutoID / RowID),由 PD 统一调度分配,保证多 TiDB 实例下的全局唯一性与高并发安全。
原因分析
在 TiDB 中:
- 自增 ID 不是单机递增,而是带有高位时间戳 + 节点信息 + 自增序列的复合结构;
- 所以生成的 ID 会是 18~20 位左右的大数;
- 即使设置了
AUTO_ID_CACHE 1,TiDB 仍然从 PD 获取全局分配的 ID 段;
- 因此 ID 不仅数值大,而且在多节点并发下也不会严格连续。
这种设计是出于 分布式一致性和扩展性 的考虑,而非异常。
实际影响
-
Java long 溢出问题
TiDB 的 ID 已经接近甚至超过 Long.MAX_VALUE (9,223,372,036,854,775,807) 的范围。
在 Java 应用中如果使用 long 类型接收,会发生溢出或抛出异常。
建议改为 String 或 BigInteger 存储 ID。
ORM 框架(如 MyBatis、JPA)也建议在实体类中把主键定义为 String。
-
JavaScript 精度丢失
JS 的 Number 类型是 64 位双精度浮点数(最大安全整数约为 2^53-1 ≈ 9.0e15),
而 TiDB 的 ID 经常超过这个范围,直接在前端显示会精度丢失、四舍五入。
前端应以字符串格式接收和展示主键 ID,禁止强转为数字。
可行解决方案
总结
TiDB 的 AUTO_INCREMENT ID 设计目标是全局唯一 + 高并发安全 + 分布式扩展性,
不是传统意义上的“连续整数主键”。
所以出现大数 ID 是比较正常现象,
但在 Java和JavaScript 等交互要注意类型溢出和精度问题,
统一用 字符串 存储和传输 ID 才是安全做法。
将其调整为AUTO_RANDOM(5, 53),不知道这样会不会有其他影响