选int还是bigint取决于业务实际最大值是否超int unsigned上限4294967295;超则必用bigint,否则int更省空间、索引更快;主键优先int unsigned,分布式id或13位以上时间戳id才需bigint。

选 INT 还是 BIGINT,关键不在“大一点更保险”,而在于你业务中这个字段**实际能取到的最大值**是否接近或超过 INT UNSIGNED 的上限(4294967295)。超了必须用 BIGINT;没超,用 INT 更省空间、索引更快、复制和备份压力更小。
主键自增ID该用INT还是BIGINT
绝大多数单机或普通分库分表场景,INT UNSIGNED 完全够用——42亿行数据不是小数目,日增 10 万条也得撑 115 年。盲目上 BIGINT 会让每条记录多占 4 字节,索引节点变大,B+树层级可能增加,查询延迟微升。
- 单体 MySQL 或中小规模业务:优先
INT UNSIGNED AUTO_INCREMENT - 分布式 ID(如 Snowflake、Leaf)、日志类高频写入表(消息 ID、埋点 ID):必须
BIGINT UNSIGNED,因为 ID 本身不连续且增长极快 - 已用
INT但监控发现auto_increment值 > 40 亿,或告警Auto-increment value is near the maximum:立刻评估迁移,别等溢出
用户ID、订单号这类业务ID怎么选
不能只看当前最大值,要看**未来 3–5 年的预期峰值**,并留出缓冲。比如当前最大订单号是 2800 万,年增长 500 万,5 年后约 5300 万 —— INT 毫无压力;但如果用的是时间戳 + 序列号拼接的 13 位毫秒级 ID(如 1715234567890),那必须 BIGINT,因为 13 位数已远超 INT 最大值 2147483647。
- 纯数字自增 ID(非全局唯一):
INT UNSIGNED是默认选择 - 含时间戳成分的长整型 ID(13 位及以上):
BIGINT是硬性要求 - 字符串型订单号(如 "ORD2026050700001"):别存整型,用
VARCHAR,否则丢失前导零、无法索引前缀
INT(11) 和 BIGINT(20) 中的数字是什么意思
INT(11) 里的 11 是显示宽度,不是存储长度,也不限制取值范围。它只在配合 ZEROFILL 时起作用(例如 INT(5) ZEROFILL 存 42 显示为 00042),但 ZEROFILL 会自动加 UNSIGNED,且现代应用层通常自行格式化,这个属性基本废弃。
- 不要写
INT(11),直接写INT或INT UNSIGNED -
BIGINT(20)同理,20不代表能存 20 位数(BIGINT最大支持 20 位无符号数,但这是由类型决定的,不是括号控制的) - 真正影响取值的是是否有
UNSIGNED,而不是括号里的数字
最容易被忽略的一点:类型一旦上线,后期改 INT → BIGINT 是 DDL 锁表操作,在大表上可能持续几分钟甚至更久,期间阻塞写入。所以初期选型要带一点前瞻性,但绝不是“一律上 BIGINT”——那是用空间和性能换来的虚假安全感。











