之前定义数据库类型一直不理解int(M)的具体含义,M决定的是什么?不同M的值的区别是什么?tinyint / smallint / mediumint / int / bigint这些类型又有什么不同?
一开始,我会以为M觉得是数据范围的大小,比如int(5)比int(3)所表示的数值范围大,但是这是完全错误的一个想法。
实际情况是M是控制数值显示的宽度,而数值范围大小跟int这个类型本身表示的范围有关。
下面通过一个具体的例子看一下:
1、验证M的具体含义,这里重点在于zerofill关键字,所以在定义字段的时候分两种情况,字段指定zerofill和不指定zerofill去测试。
– 创建表
– 字段类型为int(10) 、M为10、指定 zerofill
drop table if exists t;create table t(id int(10) zerofill)
– 插入一条位数为2位小于10位的数字10
insert into t(id) values(10)select * from t
– 查询结果显示 0000000010,前方自动补了8个0、10位显示
– 修改表结构,设置为int(3)
ALTER TABLE t CHANGE COLUMN id id INT(3) ZEROFILLselect * from t
– 这时查询结果显示 010,这时前方自动补了1个0、3位显示
– 再插入一条位数为10大于3位的数字100000
insert into t(id) values(100000)select * from t
– 查询结果显示 100000、刚才插入的10还是显示3位的010。这里未免有个疑惑,为什么不显示3位,而是原样显示,我们先打个?号。
–下面接着修改表结构,列不指定zerofill的情况
ALTER TABLE t CHANGE COLUMN id id INT(3)select * from t
– 再次查询结果:以上插入的两条数据分别显示10 、100000 ,都是原样显示。
到这里已经很清晰了,关于int(M)可以做个总结。
– 总结:int(M),M 只是控制数值显示的宽度,并且是在zerofill指定的情况下才会区别出不同。 – 如果zerofill不指定,数值显示的宽度和插入的数据保持一致。 – 如果zerofill指定,插入的数据小于指定的宽度时,前方补零,大于显示的宽度时,保持原样。
2、下面开始探索第二个问题,关于int类型可插入的数值范围是由什么决定的?
– 前面说过对于int插入的数值的大小范围跟M是没有关系的,跟int这个类型有关系,这里重点在于unsigned关键字,所以在定义字段的时候分两种情况,字段指定unsigned和不指定unsigned去测试。
– 关于int表示的数值范围:
– 有符号 -2147483648 ~ 2147483647
– 无符号 0 ~ 4294967295
– 创建表,字段默认是有符号
drop table if exists t;create table t(id int)
– 依次插入下面四个数值
insert into t(id) values(-2147483648)insert into t(id) values(-2147483649)insert into t(id) values(2147483647)insert into t(id) values(2147483648)select * from t
– 插入-2147483648,查询结果显示:-2147483648
– 插入-2147483649时报错:Out of range value for column ‘id’ at row 1 超出了可表示的值得范围
– 插入2147483647,查询结果显示:2147483647
– 插入2147483648时报错:Out of range value for column ‘id’ at row 1
– 将字段设计成无符号再进行测试
drop table if exists t;create table t(id int UNSIGNED)
– 依次插入下面四个数值
insert into t(id) values(-1)insert into t(id) values(0)insert into t(id) values(4294967295)insert into t(id) values(4294967296)select * from t
– 插入-1时报错:Out of range value for column ‘id’ at row 1
– 插入0,查询结果显示:0
– 插入4294967295,查询结果显示:4294967295
– 插入4294967296时报错:Out of range value for column ‘id’ at row 1
由此可以得出结论:插入数据的范围首先跟int类型本身可表示的数值范围有关,数值范围又分为 有符号数和无符号数。 注意:当字段指定zerofill时,字段可存储的范围也会按照无符号来进行。
3.第三个问题就是tinyint / smallint / mediumint / int / bigint这些类型有什么区别。下面看个表格。
这几种类型最大的不同在与存储的时候所占用的字节数不同,当然相应的可表示的数值的最大范围也不同。用户在定义字段类型时,可以根据自己的需求去选择。
作者:吴玉婷
更新日期:/6/7
如有问题请指出,感谢!