浮点数和定点数数据库
这二者都是用来表示小数的,浮点数包括float(单精度)、double(双精度),定点数为decimal。二者在定义时均可以指定其精度和标度,精度是指一共显示多少位数字(整数位+小数位),标度是指精确到小数点后多少位,表现形式如:decimal(15,2),这里的精度是15位(整数13位,小数2位),标度是2位。spa
须要说明的是定点数在MySQL内部是以字符串的形式来保存的,属于准确存储,3d
咱们建立一张表,字段id的数据类型为decimal(5,2)blog
向表里插入超过标度的值时,虽然插入成功可是MySQL有一个警告,查看数据咱们知道发生了四舍五入。ci
咱们再向表里尝试插入超过精度的值,难道也会发生截断并四舍五入?两个值会分别显示为123.12和124.12吗?从结果来看明显不是,咱们的猜想是彻底错误的。在超过精度的状况下,虽然插入成功但插入的值倒是指定精度和标度下的最大值,例如(5,2)下的最大值为999.99。字符串
如果在SQL Mode严格模式下,上述这些插入操做将不能被执行成功且MySQL会报ERROR。扩展
额外知识点:数据类型
如何理解单精度和双精度?float
这二者的区别若是理解为“单精度是精确到小数点后一位,而双精度是精确到小数点后两位”,那就大错特错了。实际上因为float的有效位数是7位,double的有效位数是16位,所以单精度、双精度实际上是指代这里的有效位数。im
另外须要注意的是有效位数并不等于精确位数,纵然float能够表示到小数点后7位,但只有前6位是精确的,第7位极可能形成数据偏差。而对于double来讲只有前15位是精确的,第16位也极可能形成数据偏差。
额外知识点:
关于float、double精度丢失的问题,实际上就是被扩展或截断了,究其原因是由于存取时标度不一致所致使的。在录入数据时若数据的标度与定义列数据类型时设置的标度不一致,则会致使存入时以近似的值来存储,这就形成了咱们上面说到的精度丢失。
那在什么状况下float、double的精度不会丢失呢?其实根据上面出问题的状况,咱们能够想到当数据标度与类型标度一致时(录入数据的标度与定义列数据类型时设置的标度一致),就不会发生精度丢失。
鉴于此,咱们常选用decimal类型,小于等于其标度的数据都能被正确录入,不会发生精度丢失,由于其是将数据以字符串的形式来存进数据库的,这就保证了精确性。但并非说decimal就不会发生精度丢失,由于它虽然不会发生精度扩展但却会发生精度截断,例如当录入数据的标度大于列数据类型设置的标度时,依然会发生四舍五入。
虽然咱们说decimal将数据以字符串的形式存入数据库,同时又会存在精度截断的问题(四舍五入),看似二者有文字描述上的冲突,其实否则。咱们这样来理解:decimal将发生了四舍五入的数据以字符串的形式存入了数据库,但表现出来的是小数(一个是存储形式,一个是表现形式),且这个小数的精度不会再发生变化,而无论是以什么精度来获取这个值,它都是四舍五入后以字符串形式存入时的值。