在 MySQL 里定义字段时,我们常会看到 INT(1) 和 TINYINT(1) 这样的写法。很多人以为括号里的 1 表示只能存一位数,但实际上它们背后的存储机制完全不同。INT(1) 依然是 4 字节的整数类型,而 TINYINT(1) 是 1 字节的小型整数,两者能保存的数值范围有巨大差距。

一、存储与取值范围差异
MySQL 中数值类型的字节大小是固定的,和括号里的显示宽度无关。具体对比如下:
| 类型 | 占用空间 | 有符号范围 | 无符号范围 |
|---|---|---|---|
| INT | 4 字节 | -2147483648 到 2147483647 | 0 到 4294967295 |
| TINYINT | 1 字节 | -128 到 127 | 0 到 255 |
可以看到,无论写成 INT(1) 还是 INT(10),它都是 4 字节。TINYINT(1) 也只是显示宽度为 1 的 TINYINT,存储并没有变小或变大。
二、显示宽度是什么意思
括号中的数字叫显示宽度,仅在使用 ZEROFILL 时起作用,用来在查询结果显示时左补零。例如:
CREATE TABLE test ( a INT(1) ZEROFILL, b TINYINT(1) ZEROFILL ); INSERT INTO test VALUES (5, 5); INSERT INTO test VALUES (123, 123); SELECT * FROM test; -- a 列显示 5 和 123,不会截断 -- b 列显示 5 和 123,也不会截断,但 123 已超 TINYINT 有符号范围会报错若用有符号
如果不用 ZEROFILL,显示宽度对应用层基本没影响,程序读出来就是真实数值。
三、常见误用场景
有人用 TINYINT(1) 来当布尔值,这是合理的,因为 0 和 1 都在范围内。但若用 INT(1) 存状态,虽然也能跑,却白白多占了 3 字节。反之,若用 TINYINT(1) 去存用户年龄以外的较大计数,就可能溢出。
建表建议
- 只需要存 0/1 或小型枚举,用 TINYINT 即可
- 需要大范围整数,选 INT 或 BIGINT,不必纠结括号里的数字
- 显示宽度仅关乎展示,不要把它当长度限制
四、简单验证代码
可以用下面语句直观感受区别:
-- 创建两种字段 CREATE TABLE demo ( id INT(1), flag TINYINT(1) ); -- 插入较大值 INSERT INTO demo VALUES (100000, 100); -- INT(1) 正常,TINYINT(1) 若超 127 报错 SELECT id, flag FROM demo;
综上,INT(1) 与 TINYINT(1) 在存储和范围上区别明显,括号里的 1 不是容量限制。设计表时请根据真实数据范围选类型,而不是看显示宽度。