记得刚开始使用mysql的时候,一直不太理解mysql数据类型括号里面的值,如int(5),有一次同学问了我一个问题。
同学:我要存储一个id为1471657749434601473的整数,该怎么存?
我:int(20)就欧克。
同学:为什么?
我(骄傲地回答):因为这个数有19位,我给它20够了吧
同学:你真nb!
我:算你识货!
我觉得对于刚学习mysql的人来说,或者甚至工作了几年的人来说,对于int(5),这个5的含义说不出来的大有人在,下面我们就来解释一下。
int(5)中的5的意思是显示宽度,显示宽度又是什么意思呢?在说这个5之前,先说ZEROFILL,如果没有ZEROFILL,那么5就没有任何意义,下面我们建一张表
CREATE TABLE `user` (
`id` int(5) UNSIGNED ZEROFILL NOT NULL,
`no` int NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
上面这张表一共创建了两个字段id和no,其中id我们设置了ZEROFILL,no没有设置,我们看出又有一个UNSIGNED,这又是什么玩意,其实只要我们设置了ZEROFILL,那么UNSIGNED就自动设置了,UNSIGNED就是无符号位,意思就是不能带有符号位,说白了就是最小值为0,ZEROFILL字面意思是零填充,当设置了这个值以后,如果位数不足,则用0来补,位数足或超出设置的这个位数,按int范围内的值正常显示。
插入一条数据
INSERT INTO `user`(id,no) VALUES(1,1)
从图中看出,id的值为00001,no的值为1,这下就恍然大悟了,原来是这样啊,因为id我们设置了显示宽度为5,而现在我们插入为1,那么为了凑足5位,所以
补了4个0,那么,现在可能你又有疑问了,那如果我现在插入了6位数111111,它是不是就装不下了,话不多说,我们先实验
INSERT INTO `user`(id,no) VALUES(111111,1)
上面我们插入111111,依然显示正常,并没有只显示5位,这就是我上面一直强调显示宽度这个词,因为int占4个字节,所以是32位,因为设置了无符号位
所以取值范围是0~4294967295,而111111<4294967295,所以就正常显示,所以显示宽度其实是没有任何影响的,超过显示宽度,数据依然正常显示,下面我们
再进行一个实验
INSERT INTO `user`(id,no) VALUES(4294967296,1)
此时mysql报错了,因为int的最大值是4294967295,而我们插入了4294967296,超出了最大值范围,所以报错。
由此我们可以看出,其实int(5) 和 int并没有什么区别,他们之间要有区别,还得建立在设置ZEROFILL的基础上,如果不设置ZEROFILL,那么两个没区别
不过你可能会疑惑了,既然使用了ZEROFILL,1变成了00001,那mysql怎么去存储这个数呢?难道就存00001,那数据做运算的时候怎么弄?
这里我们又要强调了一下显示宽度了,00001是让我们看到的,并不是它真的这么存储,它真实存储的数据依然是1,我们使用HEX()函数查看一下查看一下
SELECT HEX(id) , id FROM `user`
下面我们看一下mysql整型的种类和取值范围,有符号位的最小值为0,无符号位的最小值为负数,并且最小值的绝对值加上最大值等于有符号位的最大值,公式
|min| + max = UNSIGNED max
所以同学问的那个问题,用int(20)来存是不可行的,mysql会报数据太长错误,所以应该使用bigint来存储,因为存储id一般不为负,所以使用无符号位,取值范围为0~18446744073709551615。