mysql一直在更新,本文章的应用构建于 mysql-5.7.22
网上对于mysql int(11)的文章一大把,但大多讲解的不全面,自己汇集各位博主的观点做个汇总,以实际建表操作来验证这个概念
int类型的存储实际占用空间
对于int来说,存储占用4个字节
有符号的为存储数字范围为: -2147483648 -> 2147483647
无符号的存储数字范围: 0 -> 4294967295
我们先来查一下数字的字符数
2147483648
是10
个字符
4294967295
也是10
个字符
-
号占1
个字符
也就是说int
类型有
符号最多占11
字符
int
类型无
符号最多占10
字符
这里我们提到的字符
数也就是字符长度
,只是显示用途,并不与计算机实际存储有直接关系
这里你应该能理解个80%了,为什么习惯性的建表时,int(11)、int(10),而不是int(7)了
int(11) 的官方解释
大多数博客帖子,都引用了mysql官方文档的原文解释,我找了半天,我也没找到,直接抄过来吧
The number in the parenthesis does not determines the max and min values that can be stored in the integer field. The max and min values that can be stored are always fixed. The display width of the column does not affects the maximum value that can be stored in that column. A column with INT(5) or INT(11) can store the same maximum values. Also, if you have a column INT(20) that does not means that you will be able to store 20 digit values (BIGINT values). The column still will store only till the max values of INT.
翻译过来是
括号中的数字不决定可以存储在整型字段中的最大值和最小值。可以存储的最大值和最小值总是固定的。 列的显示宽度不影响可以存储在该列中的最大值。具有INT(5)或INT(11)的列可以存储相同的最大值。此外,如果您有一个INT(20)列,这并不意味着您将能够存储20位数的值(BIGINT值)。列仍然只存储到INT的最大值。
这番解释,好像懂了,又好像没懂,总之提炼出来3个关键词 显示宽度 未达到填充 不影响实际存储
以实际的案例来解释上述概念
新建一张数据表int_test
,把int可能出现情况,全部建个字段,用于更加直观的对比
ZEROFILL
:当该字段的值的长度小于定义的长度时,会在该值的前面补上相应的0
CREATE TABLE int_test (
id INT(11) NOT NULL auto_increment COMMENT '表记录',
a INT(11) NOT null COMMENT 'int11 不为空',
b INT(11) UNSIGNED ZEROFILL NOT null COMMENT 'int11 不为空 无符号 0填充',
b_1 INT(11) UNSIGNED NOT null COMMENT 'int11 不为空 无符号',
c INT(5) DEFAULT null COMMENT 'int5 可为空',
d INT(5) UNSIGNED ZEROFILL NOT null COMMENT 'int5 无符号 0填充',
e INT(15) DEFAULT null COMMENT 'int15 可为空',
PRIMARY KEY (`id`)
)
写入两条测试数据
INSERT INTO int_test (a, b,b_1, c, d, e) VALUES (1, 1, 1, 1, 1, 1);
INSERT INTO int_test (a, b,b_1, c, d, e) VALUES (1234567890, 1234567890, 1234567890, 1234567890, 1234567890, 1234567890);
查询 select * from int_test; 这里尽量不要使用第三方GUI工具,这些工具返回的内容会过滤原始填充内容
+----+------------+-------------+------------+------------+------------+------------+
| id | a | b | b_1 | c | d | e |
+----+------------+-------------+------------+------------+------------+------------+
| 1 | 1 | 00000000001 | 1 | 1 | 00001 | 1 |
| 2 | 1234567890 | 01234567890 | 1234567890 | 1234567890 | 1234567890 | 1234567890 |
+----+------------+-------------+------------+------------+------------+------------+
通过结构应该可以很直观的看出来,int(11) 这个11的作用了
总结
-
如果一个字段设置了
无符号
和填充零
属性,那么无论这个字段存储什么数值,数值的长度都会与设置的显示宽度一致,如上述例子中的字段b,插入数值1
显示为00000000001
,左边补了10个零直至长度达到11位; -
设置字段的显示宽度并不限制字段存储值的范围,比如字段d设置为
int(5)
,但是仍然可以存储1234567890
这个10
位数字; -
设置的字符宽度只对数值长度不满足宽度时有效,如
d
字段int(5)
,插入1
时,长度不足5
,因此在左边补充4
个零直到5
位,但是插入1234567890
时超过了5
位,这时的显示宽度就起不了作用了。
扩展
varchar(12) 与 char 占用空间与显示有什么不同?