引言:INT的"魔法数字"世界
在MySQL里,INT
是存储整数的"超级英雄",但它身后跟着的括号(比如INT(11)
)、ZEROFILL
和UNSIGNED
关键字却让不少人摸不着头脑。括号里的数字到底是干嘛的?ZEROFILL
为啥要把数字前面塞满0?UNSIGNED
又是个啥?别急!本文会用可爱又生动的语言,搭配一堆示例和表格,带你把这些"魔法"弄得清清楚楚!
1. 括号里的数字:显示宽度or存储范围?
当你定义一个MySQL表时,可能会看到这样的代码:
sql
CREATE TABLE users (
id INT,
age INT(2)
);
INT
后面那个(2)
是啥意思?很多小伙伴以为它限制了数字的大小,比如INT(2)
只能存2位数(0到99)。但真相是:括号里的数字只影响显示宽度,不影响存储范围!
1.1 显示宽度是啥?
显示宽度(M
)告诉MySQL在某些情况下(比如配合ZEROFILL
)如何"美化"数字的显示。它不限制能存多大的数字 ,INT
的存储范围永远由它的类型决定:
- 有符号INT(默认):-2,147,483,648 到 2,147,483,647(32位,4字节)。
- 无符号INT (加
UNSIGNED
):0 到 4,294,967,295。
括号里的M
只在以下情况起作用:
- 配合
ZEROFILL
时,决定用多少位0填充。 - 某些客户端工具(比如MySQL命令行)可能用它来格式化输出。
1.2 示例:括号有啥用?
建个表试试:
sql
CREATE TABLE test_numbers (
num1 INT,
num2 INT(5)
);
INSERT INTO test_numbers (num1, num2) VALUES (123456, 123456);
SELECT * FROM test_numbers;
结果:
num1 | num2 |
---|---|
123456 | 123456 |
发现没? num1
和num2
长得一模一样!INT(5)
并没限制num2
只能存5位数,123456照样存得下!括号里的5
在没有ZEROFILL
时基本没啥效果,顶多是给开发者一个"提示":我希望这个字段显示5位宽(但MySQL不一定听话)。
1.3 表格:括号的影响
定义 | 存储范围 | 显示效果(无ZEROFILL) | 备注 |
---|---|---|---|
INT |
-2^31 到 2^31-1 | 按实际值显示 | 括号省略,默认显示宽度11(有符号) |
INT(5) |
-2^31 到 2^31-1 | 按实际值显示 | 括号指定显示宽度5,但无ZEROFILL时无效果 |
INT(10) |
-2^31 到 2^31-1 | 按实际值显示 | 同上,显示宽度10,无ZEROFILL时无效果 |
小结 :括号里的数字(M
)只是个"装饰",不影响INT
能存多大的数字!除非搭配ZEROFILL
,否则它就像个害羞的小助手,默默待在后台。
2. ZEROFILL:给数字穿上"0"的礼服!
ZEROFILL
是个超级有趣的关键字!它告诉MySQL:"嘿,如果数字位数不够括号里的宽度,就在前面补0,给我整整齐齐!"但它必须和括号里的M
一起用,不然没效果。
2.1 ZEROFILL的魔法
- 作用 :在数字前面补0,直到达到指定的显示宽度
M
。 - 注意 :
ZEROFILL
会自动让字段变成UNSIGNED
(因为负数前面补0会很奇怪)。 - 存储:实际存储的还是原始数字,补0只影响显示。
2.2 示例:ZEROFILL的补0魔法
建个表:
sql
CREATE TABLE zero_test (
num1 INT(5) ZEROFILL,
num2 INT(8) ZEROFILL
);
INSERT INTO zero_test (num1, num2) VALUES (123, 123);
SELECT * FROM zero_test;
结果:
num1 | num2 |
---|---|
00123 | 00000123 |
哇! num1
补了2个0变成5位,num2
补了5个0变成8位!但数据库里实际存的还是123
,补0只是"化妆"效果!
2.3 再试试大数字
sql
INSERT INTO zero_test (num1, num2) VALUES (12345678, 12345678);
SELECT * FROM zero_test;
结果:
num1 | num2 |
---|---|
12345678 | 12345678 |
咦? 数字超长了,ZEROFILL
没补0!因为num1
的显示宽度是5,num2
是8,但12345678
已经超了,MySQL就直接显示原值,不补0了。
2.4 表格:ZEROFILL的效果
定义 | 插入值 | 显示结果 | 存储值 | 备注 |
---|---|---|---|---|
INT(5) ZEROFILL |
123 | 00123 | 123 | 补2个0到5位 |
INT(5) ZEROFILL |
123456 | 123456 | 123456 | 超过5位,显示原值 |
INT(8) ZEROFILL |
45 | 00000045 | 45 | 补6个0到8位 |
小结 :ZEROFILL
就像给数字穿上"0"的礼服,让它看起来整整齐齐!但它只影响显示,不改变存储值,适合需要固定宽度输出的场景(比如邮编、ID编号)。
3. UNSIGNED:让数字"摆脱负数束缚"!
UNSIGNED
关键字就像给INT
解锁了"正能量模式",让它只能存非负数,范围直接翻倍!
3.1 UNSIGNED的超能力
- 默认INT(有符号) :-2,147,483,648 到 2,147,483,647。
- UNSIGNED INT:0 到 4,294,967,295。
- 作用:去掉负数,扩大正数范围,适合存肯定不会是负数的字段(比如年龄、库存)。
3.2 示例:UNSIGNED的正能量
建个表:
sql
CREATE TABLE age_test (
age_signed INT,
age_unsigned INT UNSIGNED
);
INSERT INTO age_test (age_signed, age_unsigned) VALUES (-10, 10);
结果:
age_signed
:-10(没问题!)age_unsigned
:10(也OK!)
现在试试负数:
sql
INSERT INTO age_test (age_signed, age_unsigned) VALUES (20, -5);
结果 :MySQL会报错或把-5
转为0
(取决于SQL模式),因为UNSIGNED
字段不接受负数!
3.3 再试试大数字
sql
INSERT INTO age_test (age_signed, age_unsigned) VALUES (2147483647, 4294967295);
结果:
age_signed | age_unsigned |
---|---|
2147483647 | 4294967295 |
哇! age_unsigned
存下了超大的4294967295
,而age_signed
到2147483647
就到顶了!
3.4 表格:UNSIGNED的影响
定义 | 范围 | 允许负数? | 适用场景 |
---|---|---|---|
INT |
-2^31 到 2^31-1 | 是 | 可能有负数的字段(如余额) |
INT UNSIGNED |
0 到 2^32-1 | 否 | 非负字段(如年龄、计数) |
小结 :UNSIGNED
让INT
摆脱负数,范围翻倍,完美适合"永远正数"的场景!
4. 组合拳:ZEROFILL + UNSIGNED + 括号
ZEROFILL
和UNSIGNED
可以一起用,因为ZEROFILL
会自动让字段变成UNSIGNED
。来看个超级组合:
sql
CREATE TABLE combo_test (
num INT(5) ZEROFILL UNSIGNED
);
INSERT INTO combo_test (num) VALUES (123), (123456);
SELECT * FROM combo_test;
结果:
num |
---|
00123 |
123456 |
解析:
UNSIGNED
:确保num
只存非负数,范围0到4294967295。ZEROFILL
:给123
补0到5位,变成00123
。- 括号
(5)
:指定显示宽度,但123456
超了宽度,所以显示原值。
5. 实际场景:怎么选?
场景 | 推荐定义 | 原因 |
---|---|---|
用户ID | INT UNSIGNED |
ID肯定非负,省略括号(默认宽度够用) |
邮编 | INT(5) ZEROFILL |
需要固定5位显示(如00123),ZEROFILL自动带UNSIGNED |
账户余额 | INT |
可能有负数(如欠款),不需要ZEROFILL |
商品库存 | INT UNSIGNED |
库存不会为负,省略括号(实际值决定显示) |
格式化计数器 | INT(8) ZEROFILL |
需要8位补0显示(如00000001),适合报表或前端展示 |
6. 常见误区
- 误区1 :
INT(2)
能限制存2位数?
真相 :INT(2)
只影响显示宽度,存储范围还是-2^31到2^31-1! - 误区2 :
ZEROFILL
改变存储值?
真相 :ZEROFILL
只影响显示,数据库存的还是原始数字! - 误区3 :
UNSIGNED
和ZEROFILL
必须一起用?
真相 :可以单独用,但ZEROFILL
会自动加UNSIGNED
。
7. 结论:让INT为你所用!
MySQL的INT
类型虽然简单,但括号、ZEROFILL
和UNSIGNED
让它变得灵活又有趣:
- 括号(M) :像个"化妆师",指定显示宽度,但只在
ZEROFILL
时发光。 - ZEROFILL:给数字穿上"0"的礼服,适合需要固定宽度的场景。
- UNSIGNED:解锁正数超能力,范围翻倍,完美适合非负字段。
下次设计表时,记得根据场景挑对"装备"!是需要负数的余额?还是补0的邮编?亦或是大范围的计数器?INT
家族总能满足你!🎉
参考资料: