单库自增

数据库自增是最简单的 ID 生成方案,让我们了解它的实现和原理。

基本原理

1. 自增主键

定义: 利用数据库的自增(AUTO_INCREMENT)功能生成唯一 ID。


实现

数据设计要点

  • 核心是在 users 里保存业务事实,而不是把规则散落在应用逻辑里。
  • 索引服务于高频查询,重点是缩小扫描范围,而不是堆更多字段。
  • 查询目标是快速定位状态、任务或资源,避免在关键路径上做大范围扫描。
  • 关键字段包括 idnameemailcreated_atINSERT,它们决定后续查询和管理能力。

Java 代码


工作流程

1. 生成流程

应用程序

INSERT INTO users (name, email) VALUES (?, ?)

数据库

检查当前最大 ID

ID = MAX(id) + 1

插入数据

返回生成的 ID

应用程序

2. 事务保证


特性分析

优点

1. 实现简单 ⭐⭐⭐⭐⭐

✅ 无需额外代码
✅ 数据库原生支持
✅ 配置简单
✅ 开发效率高

2. 唯一性保证 ⭐⭐⭐⭐⭐

✅ 数据库保证唯一性
✅ 事务保证原子性
✅ 不会重复
✅ 理论和实践都保证

3. 严格递增 ⭐⭐⭐⭐⭐

✅ 严格按顺序递增
✅ 便于排序
✅ 便于范围查询
✅ 便于分页

4. 存储优化 ⭐⭐⭐⭐

✅ 使用 BIGINT(8字节)
✅ 存储空间小
✅ 索引效率高
✅ 查询性能好

缺点

1. 性能瓶颈 ⭐⭐⭐⭐⭐

❌ 需要数据库写入
❌ 网络往返时间
❌ 数据库压力
❌ QPS 受限

2. 依赖数据库 ⭐⭐⭐⭐⭐

❌ 数据库故障无法生成
❌ 单点故障
❌ 不适合分布式
❌ 扩展性差

3. 不连续 ⭐⭐⭐

❌ 删除数据后 ID 不连续
❌ 回滚事务 ID 不连续
❌ 批量插入可能有跳跃

4. 可预测性 ⭐⭐⭐

❌ 容易被推测
❌ 暴露业务量
❌ 安全性问题

性能测试

1. QPS 测试

测试环境

数据库:MySQL 8.0
硬件:4核CPU,16GB内存
表结构:简单的自增表

测试结果

单线程:5,000 QPS
多线程:50,000 QPS
连接池满:无法提升

2. 延迟测试

测试结果

本地数据库:1-5ms
远程数据库:5-20ms
高峰时段:50-100ms

3. 压力测试

结果

并发 100:正常
并发 500:延迟增加
并发 1000:连接池耗尽
并发 5000:数据库宕机

适用场景

✅ 适合使用

1. 小型系统

- 用户量 < 10万
- QPS < 1,000
- 单机部署

2. 内部系统

- 不需要高可用
- 不需要高性能
- 简单即可

3. 测试环境

- 快速开发
- 简单测试
- 不需要分布式

❌ 不适合使用

1. 大型系统

- 用户量 > 100万
- QPS > 10,000
- 需要高可用

2. 分布式系统

- 多服务节点
- 多数据库实例
- 需要水平扩展

3. 高并发系统

- 秒杀场景
- 高并发写入
- 低延迟要求

最佳实践

1. 使用连接池


2. 批量插入


3. 事务管理


常见问题

1. ID 回滚后不连续

问题

插入 ID:1, 2, 3
回滚事务
插入 ID:4, 5

ID 不连续:1, 2, 3, 4, 5

解决

  • 接受不连续
  • 使用单独的 ID 生成器
  • 使用其他方案

2. 数据库重启后 ID 跳跃

问题

重启前 ID:1000
重启后 ID:2000

ID 跳跃:1000 → 2000

原因

  • MySQL 使用缓存机制
  • 重启后重新计算

解决

  • 接受跳跃
  • 调整数据库配置

3. 并发插入时的性能

问题

高并发时:
- 锁竞争严重
- 性能下降
- 可能死锁

解决

  • 使用批量插入
  • 使用队列缓冲
  • 考虑其他方案

总结

单库自增评价

维度评分说明
唯一性⭐⭐⭐⭐⭐数据库保证
有序性⭐⭐⭐⭐⭐严格递增
性能⭐⭐性能瓶颈
可用性⭐⭐依赖数据库
扩展性不适合分布式

使用建议

推荐使用

✅ 小型系统
✅ 内部工具
✅ 测试环境
✅ 原型开发

不推荐使用

❌ 大型系统
❌ 分布式系统
❌ 高并发系统
❌ 生产核心

下一步

了解了单库自增后,我们学习集群模式的自增方案。

👉 下一节:集群模式