mysql的int(2)和int(11),这里的M代表的并不是存储在数据库中的具体的长度,不要认为为int(2)只能存储 2个长度的数字,int(11)就会存储 11 个长度的数字,这是大错特错的。
int就是占4个字节,一个字节 8 位,也就是4*8=32,所以int类型可以表示数字个数是 2的 32 次方(2^32 = 4294967296个数字)。 4294967296个数字也就是0~4294967295,当然如果区分正负号的话,表示范围是: -2147483648~ 2147483647。
int(M) 中的M指示最大显示宽度,最大有效显示宽度是 255,且显示宽度与存储大小或类型包含的值的范围无关。但是如果字段类型不指定zerofill属性,M作为显示宽度是毫无意义的。这些论述可能比较抽象,我们通过下列实验说明,int(M)到底什么意思。
如下小实验:
mysql>create table t_test_int(a int(10),b int(10) zerofill,c int(2));
Query OK, 0 rows affected (0.18 sec)
mysql>insert into t_test_int values(1111,1111,1111);
Query OK, 1 row affected (0.14 sec)
mysql>select * from t_test_int;
+------+------------+-------+
| a | b | c |
+------+------------+-------+
| 1111 | 0000001111 | 1111 |
+------+------------+-------+
1 row in set (0.00 sec)
mysql>select b from t_test_int;
+------------+
| b |
+------------+
| 0000001111 |
+------------+
1 row in set (0.00 sec)
mysql>select b+1 from t_test_int;
+------+
| b+1 |
+------+
| 1112 |
+------+
1 row in set (0.00 sec)
通过以上实验,可以总结以下3个现象。
1、我们发现int(2)字段也可以插入11111
2、b字段int(10),加了zerofill属性后,插入11111时,前面补了6个0。
3、a字段int(10) ,没有zerofill属性,插入11111时,显示11111。
根据以上现象,我们得出以下结论:
1、int(M)列,M和插入的数据大小没有关系。
2、int(M)列,加了zerofill属性,插入数值的个数不足M的,会在前面补0。通过上面最后b+1=1112我们知道,不足M位通过0补足的,只是这么显示,还是该值还是等于1111。
我们再测试边界问题,做以下实验:
mysql>create table t_test_int_02(a int(2) UNSIGNED,b int(25) zerofill,c int(2));
Query OK, 0 rows affected (0.01 sec)
mysql>insert into t_test_int_02 values (4294967295,4294967295,2147483647);
Query OK, 1 row affected (0.01 sec)
mysql>select * from t_test_int_02;
+------------+---------------------------+------------+
| a | b | c |
+------------+---------------------------+------------+
| 4294967295 | 0000000000000004294967295 | 2147483647 |
+------------+---------------------------+------------+
1 row in set (0.00 sec)
mysql>insert into t_test_int_02 (c) values (2147483648);
ERROR 1264 (22003): Out of range value for column 'c' at row 1
mysql>insert into t_test_int_02 (c) values (2147483647);
Query OK, 1 row affected (0.00 sec)
通过以上实验,我们可以总结出以下现象:
1、通过a列int(2) UNSIGNED可以存储4294967295,我们知道UNSIGNED为正,即表示只能存正整数,故范围从(0~4294967295)
2、通过c列int(2)只能存储2147483647,我们知道在int(m)的情况下,表示可以带符号表示正负,存储范围是: -2147483648~ 2147483647
3、通过b列b int(25) zerofill可以存储4294967295并且补足了0,我们知道zerofill属性与UNSIGNED等价,故范围从(0~4294967295)
以下是官方文档对int类型的介绍:
int(M)官方文档地址:
https://dev.mysql.com/doc/refman/8.0/en/numeric-type-overview.html
For integer types, M indicates the maximum display width. The maximum display width is 255. Display width is unrelated to the range of values a type can contain.
对于整数类型,M表示最大显示宽度。最大显示宽度为255。显示宽度与类型可以包含的值的范围无关,
For floating-point and fixed-point types, M is the total number of digits that can be stored.
对于浮点和定点类型, M是可以存储的总位数。
As of MySQL 8.0.17, the display width attribute is deprecated for integer data types and will be removed in a future MySQL version.
从MySQL 8.0.17开始,对于整数数据类型,不建议使用display width属性,并且在将来的MySQL版本中将删除该属性。
数据类型的范围官方文档连接:
https://dev.mysql.com/doc/refman/8.0/en/integer-types.html:
Type | Storage (Bytes) | Minimum Value Signed | Minimum Value Unsigned | Maximum Value Signed | Maximum Value Unsigned |
TINYINT | 1 | -128 | 0 | 127 | 255 |
SMALLINT | 2 | -32768 | 0 | 32767 | 65535 |
MEDIUMINT | 3 | -8388608 | 0 | 8388607 | 16777215 |
INT | 4 | -2147483648 | 0 | 2147483647 | 4294967295 |
BIGINT | 8 | -263 | 0 | 263-1 | 264-1 |