当前位置: 首页 > news >正文

SpringBoot项目里,Mybatis-Plus的主键策略(IdType)到底怎么选?AUTO、INPUT还是NONE?

Mybatis-Plus主键策略深度解析:从AUTO到ASSIGN_ID的工程实践

1. 主键设计的核心考量因素

在数据库设计中,主键的选择往往被许多开发者视为"小事",直到项目遇到性能瓶颈或数据迁移难题时才追悔莫及。Mybatis-Plus提供的多种主键策略(IdType)绝非简单的配置差异,而是关系到系统全局的基础架构决策。

主键设计的三个黄金法则

  • 唯一性:确保每条记录都有全局唯一标识
  • 稳定性:主键值一旦生成就不应改变
  • 高效性:生成算法需要考虑性能影响

以电商系统为例,订单表若采用数据库自增ID(IdType.AUTO),在分库分表场景下就会遭遇ID冲突;而用户表若使用UUID,当数据量达到千万级时,索引效率会明显下降。这些真实场景的痛点正是我们需要深入理解主键策略的原因。

2. Mybatis-Plus主键策略全景解析

2.1 AUTO:传统自增的现代困境

@TableId(type = IdType.AUTO) private Long id;

适用场景

  • 单机版MySQL/PostgreSQL应用
  • 不需要数据迁移的简单业务
  • 开发测试环境快速原型搭建

性能表现(MySQL 8.0测试数据):

并发线程数TPS(事务/秒)平均延迟(ms)
1012508
50340014
100480021

注意:AUTO策略在分布式系统中会导致ID冲突,且批量插入时需要额外处理获取ID的逻辑

2.2 INPUT:完全掌控的代价

@TableId(type = IdType.INPUT) private String customId;

最佳实践场景

  • 使用业务规则生成ID(如订单号ORD20230801-001)
  • 历史数据迁移需要保持原ID
  • 与外部系统对接需要特定ID格式

实现案例

// 使用日期+随机数生成订单ID public String generateOrderId() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); String date = LocalDate.now().format(formatter); int random = ThreadLocalRandom.current().nextInt(1000); return "ORD" + date + "-" + String.format("%03d", random); }

2.3 ASSIGN_ID:分布式时代的解决方案

@TableId(type = IdType.ASSIGN_ID) private Long distributedId;

技术原理: 基于雪花算法(Snowflake)的改良实现,64位Long型ID包含:

  • 1位符号位(固定为0)
  • 41位时间戳(约69年)
  • 10位工作机器ID(支持1024个节点)
  • 12位序列号(每毫秒4096个ID)

性能对比测试

策略类型单机QPS分布式QPSID大小
AUTO5000不支持8字节
UUID3000300032字节
ASSIGN_ID800080008字节

3. 混合策略与高级配置技巧

3.1 多租户系统的ID设计

在SaaS应用中,通常需要租户隔离与全局唯一的平衡:

@TableId(type = IdType.ASSIGN_ID) private Long globalId; @TableField("tenant_id") private String tenantId;

联合索引建议

ALTER TABLE user ADD UNIQUE INDEX idx_tenant_user (tenant_id, global_id);

3.2 自定义ID生成器

实现IdentifierGenerator接口可创建业务特定的ID生成器:

public class CustomIdGenerator implements IdentifierGenerator { @Override public Number nextId(Object entity) { // 实现自定义逻辑 return DistributedId.nextId(); } }

配置方式

mybatis-plus: global-config: db-config: id-type: assign_id identifier-generator: com.example.CustomIdGenerator

3.3 批量插入的性能优化

不同策略对批量插入的影响:

策略万条数据插入时间需要额外SQL
AUTO1200ms
ASSIGN_ID350ms
INPUT400ms

提示:使用ASSIGN_ID时,配置mybatis-plus.global-config.db-config.id-worker可优化工作节点分配

4. 决策树:如何选择最佳策略

(图示:根据业务场景选择主键策略的决策流程)

关键问题自查清单

  1. 是否需要跨数据库/分片唯一? → 考虑ASSIGN_ID
  2. 是否有历史数据迁移需求? → 考虑INPUT
  3. 是否在意存储空间和索引效率? → 避免UUID
  4. 是否需要业务含义的ID? → 自定义生成器
  5. 是否追求极致插入性能? → 对比AUTO与ASSIGN_ID

主流数据库推荐配置

数据库类型单机推荐分布式推荐
MySQLAUTO/ASSIGN_IDASSIGN_ID
PostgreSQLASSIGN_IDASSIGN_ID
OracleINPUT/SEQUENCEASSIGN_ID
MongoDBASSIGN_IDASSIGN_ID

在实际项目评审中,我通常会建议团队优先考虑ASSIGN_ID,除非有明确的业务限制。最近参与的一个物联网平台项目,从最初的AUTO迁移到ASSIGN_ID后,不仅解决了分库问题,还将插入性能提升了40%,这个经验值得分享。

http://www.jsqmd.com/news/715148/

相关文章:

  • Hacklock未来展望:AI时代下图案锁安全测试的发展趋势
  • rope集成VSCode与PyCharm:在IDE中实现智能重构
  • 2026中国钛合金棒厂家TOP4权威排名:医用钛棒/TC4钛棒首选供应商 - 深度智识库
  • (Linux)进程控制
  • LeetCode 深度优先搜索(DFS)题解
  • 猫抓浏览器扩展完全指南:免费开源资源嗅探工具终极教程
  • 从感受野计算到代码实现:用Python可视化带你彻底搞懂空洞卷积的等效卷积核
  • 3个关键步骤:实现浏览器媒体资源智能捕获的完整方案
  • axilite + ap_memory约束数组-突破单口RAM限制
  • AI赋能的个性化国际教育崛起:2026深圳国际学校革命性择校指南 - 深度智识库
  • 三步掌握SakuraFrp:内网穿透终极实战指南
  • Kodi IPTV Simple完整指南:3步搭建专业级家庭电视直播系统
  • 瑞芯微(EASY EAI)RV1126B ROS2安装
  • 你的宽带真的支持IPv6吗?手把手教你用手机热点+MobaXterm远程办公
  • 避坑指南:在Ruoyi-Vue中实现登录拦截与密码重置,我踩了这三个Token管理的坑
  • 2026年数控钣金公司实力排行/钣金,钣金加工,钣金件加工,精密不锈钢钣金加工 - 品牌策略师
  • Amulet-Map-Editor完整功能解析:从世界编辑到格式转换
  • Yew物联网:MQTT和WebSocket通信的终极指南
  • 终极Python多线程与多进程编程指南:从入门到实践的完整路径
  • 如何利用Composer二进制包支持高效分发PHP扩展和工具
  • Smithbox终极指南:如何轻松修改你最喜欢的魂系游戏
  • 一键安装HS2-HF_Patch:解锁Honey Select 2完整游戏体验的终极指南
  • OpCore Simplify:3步完成黑苹果OpenCore配置的完整指南
  • 2026年,还想要入局大模型领域的学习和工作,还来得及吗?红利期还在吗?
  • Hostinger主机稳定吗 - 麦麦唛
  • AI领域重大周记:超级学习者获11亿美元融资、生成式AI监管落地、大模型与具身智能双线突破
  • 专业级VR视频转换工具:将沉浸式3D内容转为2D格式的技术解析与实践指南
  • 告别‘XXX is not a type’:一份Qt Quick项目的.qrc文件配置保姆级指南(含CMake/QMake)
  • DIY一个低成本气象站:STM32F103C8T6核心板+OLED显示风速风向温湿度
  • 暗黑2存档编辑器实战手册:掌握游戏存档修改的终极技巧