mysql 存字符串还是浮点数_MySQL知识树 数值类型 浮点数和定点数

浮点数和定点数

这两者都是用来表示小数的,浮点数包括float(单精度)、double(双精度),定点数为decimal。两者在定义时都可以指定其精度和标度,精度是指一共显示多少位数字(整数位+小数位),标度是指精确到小数点后多少位,表现形式如:decimal(15,2),这里的精度是15位(整数13位,小数2位),标度是2位。

需要说明的是定点数在MySQL内部是以字符串的形式来保存的,属于准确存储,

f08b6b7a4cab11fa3f7b10f81fd5df25.png

我们创建一张表,字段id的数据类型为decimal(5,2)

686cd9bb51e03f15c364f0e505d886ff.png

向表里插入超过标度的值时,虽然插入成功但是MySQL有一个警告,查看数据我们知道发生了四舍五入。

43de360b674d295c1ce516e6890ef638.png

我们再向表里尝试插入超过精度的值,难道也会发生截断并四舍五入?两个值会分别显示为123.12和124.12吗?从结果来看明显不是,我们的猜测是完全错误的。在超过精度的情况下,虽然插入成功但插入的值却是指定精度和标度下的最大值,例如(5,2)下的最大值为999.99。

若是在SQL Mode严格模式下,上述这些插入操作将不能被执行成功且MySQL会报ERROR。

额外知识点:

如何理解单精度和双精度?

这两者的区别如果理解为“单精度是精确到小数点后一位,而双精度是精确到小数点后两位”,那就大错特错了。实际上由于float的有效位数是7位,double的有效位数是16位,因此单精度、双精度其实是指代这里的有效位数。

另外需要注意的是有效位数并不等于精确位数,纵然float可以表示到小数点后7位,但只有前6位是精确的,第7位很可能造成数据误差。而对于double来说只有前15位是精确的,第16位也很可能造成数据误差。

额外知识点:

关于float、double精度丢失的问题,实际上就是被扩展或截断了,究其缘由是因为存取时标度不一致所导致的。在录入数据时若数据的标度与定义列数据类型时设置的标度不一致,则会导致存入时以近似的值来存储,这就造成了我们上面说到的精度丢失。

那在什么情况下float、double的精度不会丢失呢?其实根据上面出问题的情况,我们可以想到当数据标度与类型标度一致时(录入数据的标度与定义列数据类型时设置的标度一致),就不会发生精度丢失。

鉴于此,我们常选用decimal类型,小于等于其标度的数据都能被正确录入,不会发生精度丢失,因为其是将数据以字符串的形式来存进数据库的,这就保证了精确性。但并不是说decimal就不会发生精度丢失,因为它虽然不会发生精度扩展但却会发生精度截断,例如当录入数据的标度大于列数据类型设置的标度时,依然会发生四舍五入。

虽然我们说decimal将数据以字符串的形式存入数据库,同时又会存在精度截断的问题(四舍五入),看似两者有文字描述上的冲突,其实不然。我们这样来理解:decimal将发生了四舍五入的数据以字符串的形式存入了数据库,但表现出来的是小数(一个是存储形式,一个是表现形式),且这个小数的精度不会再发生变化,而不管是以什么精度来获取这个值,它都是四舍五入后以字符串形式存入时的值。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值