以下文章来源于何先振,责编小何
浮点数可以处理小数。MySQL支持的浮点数类型,分别是:float、double、real。
float表示单精度浮点数、double表示双精度浮点数。

real默认就是double。如果把SQL模式设定为启用REAL_AS_FLOAT,那么MySQL就认为real是float。如果要启用,可以设置以下SQL:
SET sql_mode="REAL_AS_FLOAT";
复制
常见问题:
问题1:float和double 这两种数据类型的区别是什么?
float占用字节数少,取值范围小;double占用字节数大,取值范围大。
问题2:为什么浮点数类型的无符号数取值范围,只相当于有符号数取值范围的一半,也就是只相当于有符号数取值范围大于等于零的部分呢?
MySQL存储浮点数的格式与整数不同,无论有没符号都会保存符号的部分。因此,所谓的无符号取值范围,其实就是有符号数取值范围大于等于零的部分。
数据精度说明:
对于浮点类型,在MySQL中单精度值使用4个字节,双精度值使用8个字节。
MySQL 允许使用非标准语法,其他数据库可能不支持,因此如果涉及数据迁移最好不要使用:float(M,D) 或者 double(M,D)。这里,M表示精度,D表示标度。M=整数+小数、D=小数。
例如:定义float(4,2)的一个列可以显示为-99.99~99.99。如果超过这个范围会报错。
float和double类型在不指定(M,D)时,默认会按照实际的精度(由实际的硬件和操作系统决定)来显示。
浮点类型,也可以加unsigned,但是不会改变数据范围。
例如:float(3,2)加上unsigned仍然只能表示0-9.99的范围。
举栗子:
创建表

查看表结构

添加数据

查询表数据

如果插入超过精度不会报错,会出现四舍五入


如果整数位超过了范围,就报错了。

四舍五入时,进位不够时也会报错,进位变1000就不够了

float和double的精度缺陷问题:
创建表

插入数据

查询数,求和,应该是1.1的,结果不准确。

跟1.1比较时,结果也为0,说明不相等

总结:
在编程中,如果要用到浮点数,要特别注意误差问题,因为浮点数是不准确的,所以我们要避免使用“=”来判断两个数是否相等。同时,为了解决这个精度缺陷问题,MySQL引入了定点数类型:decimal。
创建表

查看表信息

放到MySQL8.0也支持显示宽度和精度

插入不指定decimal类型精度的字段f1,默认是(10,0),不能存小数,如果存了小数就四舍五入


f2字段指明decimal类型的精度为(5,2)意思是小数位2位,整数为3位,所以最大值是999.99


存在四舍五入问题


整数不能超过范围

进位,位数不够也报错,小数位995进位之后,变1000,整数位不够,所以报错。

演示decimal替换double,体现精度准确:
将之前的double类型字段的表,改成decimal类型


查看是已经修改字段成功。

继续计算总和,此时没有出现精度损失

比较时都为1,表示相等

浮点数和定点数比较
浮点数相对于定点数的优点是在长度一定的情况下,浮点类型取值范围大,但是不精准,适用于需要取值范围大,又可以容忍微小误差的科学计算场景。
定点数类型取值范围相对较小,但是精准,没有误差,适合对于精准要求极高的场景,比如:涉及金额的计算。
开发经验:
可靠性>存储空间(愿意用存储空间换可靠性),使用decimal的场景会比较多。
推荐阅读书籍