20250213 隨筆 自增id與業務id
在 数据库设计 中,通常会在业务表(Business Table)中 既使用自增 ID(Primary Key, PK),又额外增加一个业务 ID(Business ID),这样做的目的是为了兼顾 数据库性能、业务需求和数据迁移。
1. 自增 ID 和 业务 ID 的区别
类型 | 作用 | 特点 | 示例 |
---|---|---|---|
自增 ID(Auto Increment ID) | 数据库的主键(Primary Key, PK),保证唯一性 | 仅在数据库层面有意义,通常是数值型(INT、BIGINT) | 1, 2, 3, 4... |
业务 ID(Business ID) | 业务系统中唯一标识一条记录,适用于外部调用和分布式场景 | 可能是 UUID、雪花算法 ID、订单号等,通常是字符串 | 202402120001 、b3a8c5f0-92b4-4aaf-8b56-123456789abc |
2. 为什么需要同时使用自增 ID 和业务 ID?
🔹 1. 自增 ID 主要用于数据库索引,提升查询性能
- 数据库表的 主键(Primary Key)通常使用自增 ID,因为自增 ID 是 数值型,在数据库索引结构(如 B+ 树)中的存储效率更高,查询更快。
- 例如,在 MySQL InnoDB 中,主键索引是聚簇索引(Clustered Index),自增 ID 作为主键可以减少页分裂,提高插入速度。
📌 示例:用户表
CREATE TABLE user (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- 自增 ID
user_id VARCHAR(32) NOT NULL UNIQUE, -- 业务 ID
username VARCHAR(50) NOT NULL
);
如果使用 UUID 或雪花算法作为主键,由于它们是随机生成的,会导致索引分裂,影响性能。
🔹 2. 业务 ID 适用于外部系统,避免暴露数据库结构
- 自增 ID 只在数据库内部使用,但如果外部系统(如 API、前端)直接使用它,可能会有安全问题:
- 容易被爬取:攻击者可以通过顺序 ID (
id=1, id=2
) 猜测数据规模。 - 数据迁移困难:如果更换数据库,可能需要重新调整 ID 。
- 容易被爬取:攻击者可以通过顺序 ID (
- 业务 ID 更安全,可用于 API 返回给前端
- 业务 ID 通常是随机的,不可预测,不会被轻易遍历。
📌 示例:订单表
CREATE TABLE orders (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- 数据库索引 ID
order_id VARCHAR(32) NOT NULL UNIQUE, -- 业务 ID,例如 'ORD202402120001'
user_id BIGINT NOT NULL,
amount DECIMAL(10,2) NOT NULL
);
订单 ID (order_id
) 可用于 API 返回,而不会暴露数据库的 id
结构。
🔹 3. 业务 ID 适用于分布式系统
在 分布式系统 中,自增 ID 可能会带来冲突和同步问题:
- 单数据库自增 ID 适用于单机系统,但如果数据库拆分(如 MySQL 分库分表),不同数据库的 ID 可能重复。
- 业务 ID(如雪花算法、UUID)可以保证唯一性,适用于跨数据库、跨系统场景。
📌 分布式订单系统
订单 | 订单 ID (order_id) | 自增 ID (id) |
---|---|---|
A | ORD202402120001 | 1 |
B | ORD202402120002 | 2 |
C | ORD202402120003 | 3 |
即使数据库迁移或分库,业务 ID 仍然唯一,不受影响。
3. 业务 ID 生成方式
✅ 雪花算法(Snowflake ID)
- Twitter 开发的分布式 ID 生成算法,支持趋势递增。
- 64 位整数,结构:
时间戳 + 机房 ID + 机器 ID + 序列号
- 适合订单 ID、用户 ID、支付流水号等
📌 示例
1676217600000(时间戳)+ 01(机房)+ 01(机器)+ 0001(序列号)
✅ UUID(通用唯一标识符)
- 32/36 位的字符串,格式如:
b3a8c5f0-92b4-4aaf-8b56-123456789abc
- 适合用户 ID、Session ID
- 缺点:索引性能比整数 ID 差。
📌 示例
SELECT UUID(); -- 生成 UUID
✅ 自定义规则(如时间戳 + 递增序列)
- 订单号
ORD202402120001
- 用户 ID
USR2024021201
4. 结论
使用方式 | 自增 ID(id) | 业务 ID(business_id) |
---|---|---|
作用 | 数据库主键,优化索引 | 业务使用,外部系统唯一标识 |
类型 | BIGINT AUTO_INCREMENT | VARCHAR(32) / BIGINT |
特点 | 快速查询,索引优化 | 唯一、不连续,适用于 API 和分布式系统 |
示例 | 1, 2, 3... | b3a8c5f0-92b4-4aaf-8b56-123456789abc 、ORD202402120001 |
使用场景 | 内部数据库 | 订单号、用户 ID、支付流水号等 |
最佳实践
- 数据库主键用自增 ID,提高查询效率(尤其是 MySQL InnoDB)。
- API / 业务层返回业务 ID,避免暴露数据库结构。
- 分布式系统用雪花算法或 UUID 生成业务 ID,确保全局唯一。
💡 总结:
- 自增 ID 用于 数据库主键,提升查询性能。
- 业务 ID 用于 外部系统,增强安全性,支持分布式架构。
👉 这样设计可以同时兼顾数据库性能和业务需求,确保数据唯一性、可迁移性和安全性! 🚀