背景
相信大家都有过这种经历,建表的时候id字段一般都会默认设置为int(11).
我们知道char(10),varchar(10)这种都是指占用多少个字节,比如用char(10)存储‘1234567890ab’,会被截断成’1234567890’,因为超过了指定长度10。
那么int(11)中的11是代表占了多少个长度么?
疑问int类型定义
整形跟char、varchar不同int最大值,整形分为tinyint,smallint,mediumint,bigint
根据上图我们可以看到int类型可以表示的范围最大能到4294967295。
既然已经根据长度不同,内置了整形的不同类型,那么int(1)和int(11)有什么区别?
官方解释
其实想知道他们的区别直接看mysql手册即可,这也是最靠谱的办法
int(M): M indicates the maximum display width for integer types.1
在 integer 数据类型中,M 表示最大显示宽度。
原来,在 int(M) 中,M 的值跟 int(M) 所占多少存储空间并无任何关系。
int(3)、int(4)、int(8) 在磁盘上都是占用 4 btyes 的存储空间。
说白了,除了显示给用户的方式有点不同外,int(M) 跟 int 数据类型是相同的。
动手实践
我们来新建一张表
CREATE TABLE `test` (
`id` int(1) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
test表id为int(1)
然后插入int可以表示的最大值4294967295
mysql> INSERT INTO `test` (`id`) VALUES (4294967295);
Query OK, 1 row affected (0.00 sec)
我们可以看到是可以插入成功的,而且也是可以保存下来的。
所以由此说明int(M)中的M和存储的数据长度是没什么关系的。
换句话说int(11)能存储多大的数字,那么int(1)就能存储多大的数字
zerofill
根据上面的结论int(11)和int(1)表示的数字的范围是一样的,那么设置int(M)中的M的意义是什么呢?其实设置M得和zerofill结合起来才会生效
我们先看个例子
CREATE TABLE `test` (
`id` int(4) unsigned zerofill NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
注意int(4)后面加了个zerofill,我们先来插入4条数据。
mysql> INSERT INTO `user` (`id`) VALUES (1),(10),(100),(1000);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
然后我们来查询下
mysql> select * from test;
+------+
| id |
+------+
| 0001 |
| 0010 |
| 0100 |
| 1000 |
+------+
4 rows in set (0.00 sec)
通过数据可以发现 int(4) + zerofill实现了不足4位补0的现象,单单int(4)是没有用的。而且对于0001这种,底层存储的还是1,只是在展示的会补0。
总结
int(M)中的M并不能表示数字的长度,int(M)得和zerofill配合使用,才有效果int最大值,简单说就是零填充的作用。