应按未来5–8年数据规模选择主键类型:未超INT UNSIGNED上限(429亿)用INT UNSIGNED,否则直接BIGINT UNSIGNED;需同步更新外键、应用层类型及ORM映射,避免截断或锁表风险。

不是所有表都该用 BIGINT UNSIGNED,但当你确认主键年增超千万、或已有 Auto_increment 值接近 INT UNSIGNED 上限(4294967295)时,它确实是更稳妥的选择——核心不是“阿里强制”,而是 B+ 树索引结构 + 自增逻辑 + 长期运维成本共同决定的。
为什么B+树会让INT和BIGINT的代价差异被放大
MySQL 的聚簇索引(即主键索引)是 B+ 树实现的,每一层节点都要存主键值做路由:非叶子节点存 key + 指针,叶子节点存整行数据。这意味着:
-
INT占 4 字节,BIGINT占 8 字节——单行多 4 字节,但放大到亿级表的 B+ 树上,可能让索引体积多出几十 GB - 所有二级索引的叶子节点,也会冗余存储主键值;如果联合索引以主键开头(比如
(id, created_at)),那每个二级索引条目都多占 4 字节 - 更大的索引 → 更多磁盘页 → 更难缓存进
innodb_buffer_pool_size→ 查询延迟上升、IO 压力变大
所以“建议用 BIGINT UNSIGNED”的前提,其实是你已经确定未来几年主键会撑满 INT,而不是一上来就默认选它。
为什么必须是 UNSIGNED 而不是普通 BIGINT
BIGINT 默认是有符号的,取值范围是 -9223372036854775808 到 9223372036854775807;而 BIGINT UNSIGNED 是 0 到 18446744073709551615。自增主键从不为负,用有符号纯属浪费一半空间。
-
AUTO_INCREMENT默认从 1 开始递增,永远只走正向,负数区间完全闲置 - 如果误用有符号
BIGINT,实际可用 ID 数量直接砍半(只剩约 9.2e18),且应用层容易因类型映射错误导致截断(比如 Java 用long接收,但数据库返回的是无符号超限值) -
SERIAL类型本质就是BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,MySQL 官方也默认推荐这个组合
什么时候不该盲目切 BIGINT UNSIGNED
很多团队看到“主键快用完”就立刻执行 ALTER TABLE ... MODIFY COLUMN id BIGINT UNSIGNED,结果发现根本没必要——甚至引发外键断裂、ORM 映射失败、Java 截断等线上事故。
- 先查真实增长速率:
SELECT COUNT(*) FROM orders WHERE create_time > DATE_SUB(NOW(), INTERVAL 1 YEAR); - 再算剩余容量:
SELECT (4294967295 - MAX(id)) AS remaining FROM orders;(注意:这不准,要以SHOW TABLE STATUS LIKE 'orders'中的Auto_increment值为准) - 年增 500 万,
INT UNSIGNED还能撑 800 多年;年增 2000 万,也还能撑 20 年——真没必要现在就切 - 如果只是短期峰值(比如营销活动导致 ID 猛增),可临时调大
auto_increment_increment或改起始值,比 DDL 更轻量
线上改主键类型,最容易漏掉的三件事
把 id 从 INT 改成 BIGINT UNSIGNED 不是改一个字段那么简单,漏掉任何一项都可能让服务挂掉。
- 所有外键字段必须同步改:
ALTER TABLE order_items MODIFY COLUMN order_id BIGINT UNSIGNED;,否则 DDL 直接报错 “Cannot change column used in a foreign key constraint” - Java 层变量类型要对齐:不能用
int或long直接接收(long虽能装下,但 JDBC 驱动对无符号BIGINT的处理不一致,部分版本会溢出为负数),稳妥做法是用BigInteger或String接收 - ORM 映射必须更新:MyBatis 的
resultType、Hibernate 的@Column(columnDefinition = "BIGINT UNSIGNED")、Lombok 的@Data生成 getter/setter 也要检查是否适配
真正关键的不是“能不能用 BIGINT UNSIGNED”,而是你有没有验证过它带来的索引膨胀是否可接受、有没有覆盖全部关联字段和应用层类型——这些细节,往往比选型本身更决定成败。


















