整型 TINYINT 到 BIGINT 的存储差异与选择策略
MySQL 整型类型一览
MySQL 提供了 5 种整型,区别在于存储空间和取值范围:
| 类型 | 字节数 | 有符号范围 | 无符号范围 |
|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 |
| SMALLINT | 2 | -32,768 ~ 32,767 | 0 ~ 65,535 |
| MEDIUMINT | 3 | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 |
| INT | 4 | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 |
| BIGINT | 8 | -2^63 ~ 2^63-1 | 0 ~ 2^64-1 |
核心差异解析
1. 存储空间差异
- TINYINT (1字节):节省空间的效果最明显。如果有 1000 万行数据,TINYINT 比 INT 省 30MB,比 BIGINT 省 70MB
- INT (4字节):最通用的选择。绝大多数场景够用
- BIGINT (8字节):空间翻倍。除非必要(自增主键预估超过 42 亿),不建议滥用
一个典型误区:用户状态字段(0/1/2)用 INT,完全可以改用 TINYINT。
2. 显示宽度(ZEROFILL)
MySQL 允许指定 INT(11) 这样的显示宽度,但这不影响存储空间和取值范围。显示宽度仅在使用 ZEROFILL 时有效,用于补零显示。从 MySQL 8.0.17 起,显示宽度已被废弃,不再建议使用。
3. 有符号 vs 无符号
MySQL 对整个列的声明决定有符号或无符号:
age TINYINT UNSIGNED -- 0~255,适合年龄
status TINYINT -- -128~127,默认有符号
如果业务上值不会为负数,加上 UNSIGNED 可以扩展上限一倍。但要注意:MySQL 中两个 UNSIGNED 整数相减结果还是 UNSIGNED,可能导致意外的环绕行为。
4. 自增主键的选择
这是整型选择最常见的面试题:
- INT UNSIGNED:最大 42.9 亿,一般业务足够
- BIGINT UNSIGNED:几乎用不完,适合高并发或超大量数据业务
- 如果使用分布式 ID(雪花算法等),ID 超过 INT 上限,必须用 BIGINT
一个常见的生产事故:某表自增主键用 INT 达到上限,INSERT 报 Duplicate entry 或 Out of range 错误,导致业务中断。因此,对可能增长到亿级的表,建议直接使用 BIGINT。
5. 布尔值的表示
MySQL 没有真正的布尔类型。BOOL 和 BOOLEAN 只是 TINYINT(1) 的别名:
– 0 = false
– 非 0 = true(通常用 1)
相比之下,如果用 BIT(1) 存储布尔值,虽然更语义化,但 BIT 类型在查询优化上不如 TINYINT 友好(不能走索引、比较时类型转换多)。
6. 性能差异
在 CPU 层面,操作不同宽度的整数对现代处理器来说差异极小。主要性能差异来自:
– 内存占用:BIGINT 占缓冲池更多空间,减少缓存行数
– IO 带宽:更大的类型意味着更大的行记录,每次 IO 能读的行数减少
– 索引大小:主键为 BIGINT 时,二级索引也隐式包含主键,导致二级索引变大
选择策略
| 场景 | 推荐类型 | 理由 |
|---|---|---|
| 状态/标志/性别 | TINYINT | 值范围小,节省空间 |
| 年龄/评分/小分类 | TINYINT UNSIGNED | 正数范围够用 |
| 中量级枚举(<32000) | SMALLINT | 比 INT 省一半空间 |
| 普通 ID / 计数器 | INT UNSIGNED | 平衡空间和取值 |
| 预计超 42 亿的主键 | BIGINT | 防溢出 |
| 分布式 ID | BIGINT | 雪花算法等生成值超 INT 范围 |
| 金额(分) | INT 或 BIGINT | 如果金额大需 BIGINT |
面试常见追问
Q:为什么不用 VARCHAR 存数字?
A:数字类型比字符串排序更高效(二进制比较 vs 字典序),占用空间更小,且保证计算正确性(’2′ > ’10’ 的问题)。
Q:INT(10) 和 INT(1) 有区别吗?
A:没有。存储空间和取值范围相同,显示宽度仅配合 ZEROFILL 使用,8.0.17+ 已废弃。
Q:自增主键用 BIGINT 有什么缺点?
A:占 8 字节(INT 的两倍),导致聚簇索引更大、二级索引更大、缓冲池缓存行数减少。但对多数场景来说,避免溢出的收益远大于这额外空间成本。


暂无评论内容