你是不是也曾经在创建数据库表时,对着 INT(3)、INT(11) 这样的类型定义犹豫过?心里可能在想:
“
INT(11)是不是比INT(3)能存更大的数字?”
“是不是INT(3)更省空间?”
“这个括号里的数字到底啥意思?🤔”
别担心,你不是一个人!很多刚开始接触 MySQL 的朋友都有过这种困惑。今天,我们就来彻底揭秘这个“括号里的数字”的真实身份,答案可能会让你大跌眼镜!
核心结论抢先看:
INT(3)和INT(11)在存储空间、能存的数字大小范围上,完!全!一!样!那个括号里的数字 (
3或11),仅仅是个“显示宽度”的提示,而且只在特定情况下才起作用!
是不是感觉有点意外?别急,我们慢慢道来。
一、深入本质:INT 的“硬实力”是固定的
- • 存储空间: 无论你写
INT(1)、INT(3)、INT(11)还是INT(100),在数据库硬盘上,它们都稳稳地占据着 4个字节 的空间。就像一个小盒子,尺寸是固定的。 - • 数字范围: 这个固定的“盒子”能装下的数字大小也是固定的:
-
- • 有符号整数(可正可负): 从
-2,147,483,648到2,147,483,647(大约 -21亿 到 +21亿)。 - • 无符号整数(只存正数): 从
0到4,294,967,295(大约 0 到 42亿)。
- • 有符号整数(可正可负): 从
划重点: INT(3) 和 INT(11) 的“盒子”大小和容量完全一致!INT(3) 绝对能存下 123456 这样的大数,INT(11) 也绝不会比 INT(3) 能存更大的数!
二、括号里的数字 (M):神秘的“显示宽度”
既然存储都一样,那 (3) 和 (11) 的区别到底在哪?答案就在 “显示宽度” (Display Width) 这个概念上。
- • 它是什么? 你可以把它想象成一个 “建议的显示位数” 或者 “格式化提示” 。
- • 它有什么用? 主要用在
ZEROFILL属性上! 这是关键!
场景实验:当 ZEROFILL 出场时
假设我们创建这样一张表:
CREATE TABLE test_numbers (
small_display INT(3) ZEROFILL, -- 显示宽度为3,启用零填充
large_display INT(11) ZEROFILL -- 显示宽度为11,启用零填充
);
现在,我们插入一些数字:
INSERT INTO test_numbers (small_display, large_display) VALUES
(5, 5),
(42, 42),
(123, 123),
(1234, 1234); -- 注意:1234 超过了 small_display 的显示宽度 3
神奇的事情发生了!查询一下 (SELECT * FROM test_numbers;):
| small_display | large_display |
|---|---|
| 005 | 00000000005 |
| 042 | 00000000042 |
| 123 | 00000000123 |
| 1234 | 00000001234 |
发生了什么?
- 1.
ZEROFILL的作用: 当字段启用了ZEROFILL,MySQL 在显示这个整数值时,如果数字本身的位数 小于 括号里指定的显示宽度 (M),它会在数字的左边用0填充,直到达到指定的宽度。 -
- •
small_display INT(3) ZEROFILL:显示宽度是 3。 -
- • 存
5(1位数) -> 显示005(左边补两个0) - • 存
42(2位数) -> 显示042(左边补一个0) - • 存
123(3位数) -> 显示123(刚好,不用补) - • 存
1234(4位数) -> 显示1234(超出宽度?照样显示!不截断!不报错!)
- • 存
- •
large_display INT(11) ZEROFILL:显示宽度是 11。 -
- • 存
5-> 显示00000000005(左边补10个0) - • 存
1234-> 显示00000001234(左边补7个0)
- • 存
- •
- 2. 关键结论:
-
- • 括号里的数字
M(3或11) 只在ZEROFILL启用时影响显示效果(左边补零) 。 - • 它绝不限制你能存储的数字大小!
INT(3)的字段存123456完全没问题,显示时如果没有ZEROFILL就是123456,有ZEROFILL就是123456(因为123456 > 3位,不补零)。 - • 它也不节省任何存储空间!补零只是在查询结果显示时做的格式化,硬盘上存的还是原始数字
5、42、123、1234。
- • 括号里的数字
三、重要注意事项 & 现代实践
- 1.
ZEROFILL的副作用: 一旦给字段加上了ZEROFILL,MySQL 会自动把这个字段变成UNSIGNED(无符号整数,只能存非负数)。如果你试图存负数进去,会报错。 - 2. MySQL 8.0+ 的弃用:
ZEROFILL属性在 MySQL 8.0 版本已被标记为废弃 (Deprecated)! 官方不推荐在新项目中使用它,未来版本可能会移除。主要原因是这种格式化显示的工作,更适合放在应用程序层面(比如你的 PHP, Python, Java 代码)或者报表工具里去做,用LPAD()函数或者字符串格式化功能就能轻松实现左边补零。 - 3. 没有
ZEROFILL时: 如果你的字段定义是INT(3)或者INT(11),但没有加ZEROFILL属性,那么这个括号里的数字 (M) 就只是一个非常微弱的提示信息,绝大部分客户端(包括命令行、phpMyAdmin、各种数据库工具)在显示数字时会忽略它。它几乎没有任何实际效果。你存5,它就显示5;你存123456,它就显示123456。
四、终极结论 & 你应该怎么做
- •
INT(3)和INT(11)的核心区别: 仅在启用ZEROFILL时,影响查询结果中数字左侧补零的位数。INT(3) ZEROFILL最少补足到3位显示,INT(11) ZEROFILL最少补足到11位显示。它们不改变存储空间,不改变数值范围! - • 现代开发最佳实践:
-
- 1. 避免使用
ZEROFILL: 尤其是在 MySQL 8.0 及以上版本。把数字格式化的任务(比如工号补零、日期补零)交给你的应用程序代码或前端展示层。 - 2. 简化你的 INT 定义: 如果你不需要
ZEROFILL(或者根本不知道它干嘛用的),那么在定义整数字段时,直接写INT就够了! 括号里的数字 (M) 完全可以省略。写成INT和写成INT(11)(INT的默认显示宽度是 11)在功能上没有任何区别,而且INT更简洁清晰。 - 3. 别再纠结括号里的数字: 看到
INT(10)也不要慌,它和INT(1)、INT(20)在存储上依然是一样的!那个数字对存储和范围毫无影响。
- 1. 避免使用
总结一句话
MySQL 中
INT后面括号里的数字 (M),就是个负责“颜值”(显示时左边补零)的“小助手”,跟INT本身的“实力”(存储空间和数值范围)没有 毛线关系!在绝大多数情况下,放心大胆地直接用INT就好啦!💪🏻
希望这篇文章能彻底解开你对 INT(3) 和 INT(11) 的疑惑!下次看到它们,或者看到同事用了 INT(10),你就可以淡定地分享这个知识点了!😉
公众号:BiggerBoy | 作者:北哥
欢迎关注【BiggerBoy】公众号,技术干货持续奉上!