聊一聊 int(1) 和 int(11) 的区别

我们知道char(10),varchar(10)这种都是指占用多少个字节,比如用char(10)存储‘1234567890ab’,会被截断成’1234567890’,因为超过了指定长度10。

但是整形跟char、varchar不同,整形分为tinyint,smallint,mediumint,bigint

类型 字节 有符号最小值 有符号最大值 无符号最小值 无符号最大值
tinyint 1 -128 127 0 255
smallint 2 -32768 32767 0 65535
mediumint 3 -8388608 8388607 0 16777215
int 4 -2147483648 2147483647 0 4294967295
bigint 8 -9223372036854775808 9223372036854775807 0 18446744073709551615

既然已经根据长度不同,内置了整形的不同类型,那么int(1)和int(11)有什么区别了?

int(M)我们先来拆分,int是代表整型数据那么中间的M应该是代表多少位了,后来查mysql手册也得知了我的理解是正确的,下面我来举例说明。

MySQL 数据类型中的 integer types 有点奇怪。你可能会见到诸如:int(3)、int(4)、int(8) 之类的 int 数据类型。刚接触 MySQL 的时候,我还以为 int(3) 占用的存储空间比 int(4) 要小, int(4) 占用的存储空间比 int(8) 小。
后来,参看 MySQL 手册,发现自己理解错了。

  1. 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 数据类型是相同的。
另外,int(M) 只有跟 zerofill 结合起来,才能使我们清楚的看到不同之处。

  1. mysql> drop table if exists t;
  2. mysql> create table t(id int zerofill);
  3. mysql> insert into t(id) values(10);
  4. mysql> select * from t;
  5. +------------+
  6. | id |
  7. +------------+
  8. | 0000000010 |
  9. +------------+
  10. mysql> alter table t change column id id int(3) zerofill;
  11. mysql> select * from t;
  12. +------+
  13. | id |
  14. +------+
  15. | 010 |
  16. +------+
  17. mysql>
  18. mysql> alter table t change column id id int(4) zerofill;
  19. mysql> select * from t;
  20. +------+
  21. | id |
  22. +------+
  23. | 0010 |
  24. +------+
  25. mysql>
  26. mysql> insert into t(id) values(1000000);
  27. mysql> select * from t;
  28. +---------+
  29. | id |
  30. +---------+
  31. | 0010 |
  32. | 1000000 |
  33. +---------+

从上面的测试可以看出,“(M)”指定了 int 型数值显示的宽度,如果字段数据类型是 int(4),则:当显示数值 10 时,在左边要补上 “00”;当显示数值 100 是,在左边要补上“0”;当显示数值 1000000 时,已经超过了指定宽度“(4)”,因此按原样输出。 在使用 MySQL 数据类型中的整数类型(tinyint、smallint、 mediumint、 int/integer、bigint)时,非特殊需求下,在数据类型后加个“(M)”,是没有任何意义的。

int(1)和int(11)在实际使用中,如果不使用 zerofill 是没有任何区别的,而且int型最大只能存储4294967295这个整数,我们可以发现其实只有10位。

综上所述,当我们需要用整形来存储一个字段类型的时候,应该尽量估算出该字段所需要的实际长度,比如tinyint可存储无符号最大值是255(1个字节长度,即2的8次方),smallint可存储无符号最大值是65535(2个字节长度,即2的16次方),mediumint可存储无符号最大值是16777215(3个字节长度,即2的24次方),而int型最大可存储4294967295(3个字节长度,即2的32次方)