背景

相信大家都有过这种经历,建表的时候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最大值,简单说就是零填充的作用。