本文系统讲解 MySQL 数字类型字段的设计方法,从类型选择、NOT NULL、DEFAULT 默认值到金额精度与状态字段建模,提供面向大型系统的数据库设计实践,帮助开发者构建高可维护、高性能且具备长期扩展能力的表结构。
数据库主键:该选 int 还是 bigint?一场关于“工程直觉”与“心智负担”的博弈
数据库主键:该选 int 还是 bigint?一场关于“工程直觉”与“心智负担”的博弈
在设计数据库表结构时,主键(Primary Key)的选择往往是我们的“第一步”。很多开发者在此时会产生一个疑问:“我的表数据量预计也就几万条,甚至只是存几十行配置,有必要用 bigint 吗?统一用 int 是不是更省空间?”
今天,我们就来深度拆解这个看似微小、实则影响深远的工程决策。
1. 21 亿的“隐形炸弹”
很多人选择 int 的理由是:int 的最大值约为 21 亿 ($2^{31}-1$)。在大多数人的直觉里,这是一个天文数字,一辈子也用不完。
但现实往往是残酷的:
- 业务增长的非线性:一个起初只打算存用户信息的表,可能因为后来引入了“用户行为日志”或者“第三方数据同步”,在短短几个月内就冲破了 21 亿的关口。
- 历史教训:YouTube 曾经就因为视频点击量超过了
int的上限,导致系统崩溃,最后不得不紧急迁移到bigint。
结论: 在大数据时代,21 亿不再是不可逾越的鸿沟。
2. “事后补救”的代价
如果你在数据量达到 20 亿时才意识到要改类型,你将面临数据库运维中最痛苦的时刻:在大表上执行 DDL(数据定义语言)操作。
- 锁表风险:在旧版本的数据库中,修改字段类型需要重建整张表,这会导致业务长时间停机。
- 迁移成本:即便使用
gh-ost等在线变更工具,处理数十亿行数据的字段升级也需要耗费数天甚至数周的时间,且伴随着巨大的数据一致性风险。
与其在未来某个深夜加班修库,不如在建表的第一天多花 4 个字节。
3. 微观优化 vs. 宏观效率
有人会争论:配置表明明只有几百行,用 bigint 简直是浪费。
让我们算一笔账:
int占 4 字节,bigint占 8 字节。- 对于一张 1000 行的配置表,两者差距仅为 4 KB。
- 在当今内存以 GB 计、磁盘以 TB 计的服务器环境下,这 4 KB 的空间节省几乎无法带来任何性能提升。
相反,“统一规范”带来的收益远大于“按需分配”:
- 降低心智负担:开发者无需在每次建表时反复纠结。
- 代码一致性:后端代码中的 Entity 对象可以统一使用
Long类型,避免在关联查询或接口对接时出现类型溢出或不匹配。 - 兼容分布式 ID:如果你未来需要引入雪花算法(Snowflake)等分布式 ID 生成器,
bigint是唯一的硬性要求。
4. 什么时候该选 int?
虽然我倾向于“无脑 bigint”,但在极少数场景下,int(甚至 smallint)仍有其价值:
- 超大规模且索引密集的表:如果你有一张数百亿行的表,且表上有 10 个以上的二级索引。此时主键从 8 字节降为 4 字节,能显著缩小索引文件体积,提升 Buffer Pool 的命中率。
- 严格定义的静态字典:比如“性别”、“省份编码”,这些数据量有物理上限,绝无可能突破千万级。
5. 最终建议:我们的工程哲学
在现代软件工程中,“可维护性”和“容错性”的权重通常高于“微小的空间优化”。
- 如果是业务表(用户、订单、流水、日志):请务必使用
bigint unsigned。 - 如果是配置表(菜单、权限、系统参数):即便预计只有几百行,为了规范统一,也建议首选
bigint。
总结一句话:不要为了节省那几块钱的硬盘空间,去埋下一个可能导致全线宕机的隐患。