# 数字类型 INTEGER SMALLINT NUMERIC

关键字中的a/b代表a和b是同义词,可以互相替代

# 1.二进制数字类型&bool类型

关键字 长度限制 占用存储空间 表示数字范围
BIT M 长度有关 -9223372036854775808 to 9223372036854775807
BOOL/BOOLEAN -- 8bit(1Bytes) 0,1
  • 二进制类型:长度比较特殊代表的是二级制数长度,其它的数字类型都是指的自然数长度。如果长度设置1,那么只能保存0,1,其实就是1位二级制数,如果是2,那么就是2位二级制数。M的最大值为64,也就是最大能表示4bytes的数据
  • bool类型: 不能设置长度,只有2个值true和false。但是插入数据的时候插入的0和1。

# 2.整数类型

关键字 长度限制 占用存储空间 表示数字范围
TINYINT M 8bit(1Bytes) -128~127
SMALLINT M 16bit(2Bytes) -32768 to 32767
MEDIUMINT M 24bit(3Bytes) -32768 to 32767
INT/INTEGER M 32bit(4Bytes) -2147483648 to 2147483647
BIGINT M 64bit(8Bytes) -9223372036854775808 to 9223372036854775807
  • 这种整数类型字段行,长度都是固定的,占用空间也是固定的。设置M值本省并没有意义。
  • UNSIGNED, 在申明字段的时候,这写字段都可以设置。如果设置UNSIGNED,那么该字段将没有符号,表数字的范围将翻倍,比如TINYINT将表示0~255
  • ZEROFILL,mysql会自动加上unsigned
  • AUTO_INCREMENT 自增字段(),设置该属性时,这个字段必须是索引,可以是普通索引,也可以是主键索引

# 3.浮点类型

关键字 长度限制 占用存储空间 备注
FLOAT M,D 32bit(4bytes)
DOUBLE/DOUBLE PRECISION/REAL M,D 64(8bytes)
  • float/double这个类型容易精度丢失,涉及需要高精度的敏感数据就需要decimal类型。
  • M就是数字整体位数(不含符号和小数点),D是小数点后的数字长度,例: testb decimal(5,3), 代表testb保存-99.999~99.999之间的数字
  • UNSIGNED代表无符号数,但是在浮点类型,数字表示范围不会扩大,只是会阻止负数存储。
  • ZEROFILL,mysql会自动加上unsigned
  • AUTO_INCREMENT 自增字段(表中只能有一个字段),设置该属性时,这个字段必须是索引,可以是普通索引,也可以是主键索引

# 4.精确类型

关键字 长度限制 占用存储空间 备注
DECIMAL/DEC/NUMERIC/FIXED M,D M最大65(默认10),D最大(默认0)
  • float为了兼容ODBC,当不设置D时,M>25,那么float自动转换为duble类型,并且这个时候的M将不限制总位数。
  • decimal/float/double小数位数如果没有指定,那么最大值取决于硬件设备限制和系统设置。
  • UNSIGNED代表无符号数,但是在精确类型,数字表示范围不会扩大,只是会阻止负数存储。
  • ZEROFILL,mysql会自动加上unsigned

建议使用decimal/float/duble时候建议指定M,D,否则取决于系统和硬件,精度将变成可变

# 5.实操实验

# 自增字段插入空&负数实验

CREATE TABLE `test` (
  `testb` int zerofill not null auto_increment,
  `testd` int zerofill,
  index testb(testb)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert test(testb) values(null);

select * from test;

执行结果1:

testb testd
1 [NULL]
insert test(testb) values(-1);
select * from test;

执行结果2:

testb testd
1 [NULL]
-1 [NULL]

执行结果1证明了当自增字段插入一个null的时候,mysql会给它设置一个自增值。 官方文档里面说自增字段不能设置复制不支持,但是执行结果2证明设置负数是可以的。

# zerofill自动添加unsigned实验

CREATE TABLE `test` (
  `testb` int zerofill
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

show create table test;

结果:

Table Create Table
test CREATE TABLE test (
testb int(10) unsigned zerofill DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

# float/double精度丢失实验

依次执行:

CREATE TABLE `test` (
  `testb` float(10,6)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert test(testb) values("32.214");

select * from test;

最终执行结果:

testb
32.214001

从结果上来看最后一位多了一个1,这个和我们实际生活中期望的32.214是有出入的。

# float只设置M的实验

CREATE TABLE `test` (
  `testb` float(24)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
show create table test;

结果:

Table Create table
test CREATE TABLE test (
testb float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
drop table test;
CREATE TABLE `test` (
  `testb` float(25)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
show create table test;

结果:

Table Create table
test CREATE TABLE test (
testb double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

从结果上看括号内是24的时候创建了一个float类型没有长度的字段,括号内是25的时候创建的字段自动变成了double

# decimal超过声明小数位数实验

依次执行

CREATE TABLE `test` (
  `testb` decimal(4,3)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert test(testb) values("1.3126");

select * from test;

最终执行结果:

testb
1.313

mysql官方文档描述,decimal类型字段,小数位数超过了字段申明位数,那么会截取字段声明位数。 至于超过四舍五入还是直接抹去和操作系统有关,我用的centos是四舍五入。