浮点数(Floating-Point Types)
MySQL支持两种浮点数类型来表示近似值:
1、FLOAT,单精度浮点数,使用4字节存储,存储数据范围3.402823466E+38 - -1.175494351E-38,0,1.175494351E-38 - 3.402823466E+38
2、DOUBLE,双精度浮点数,使用8字节存储,存储数据范围-1.7976931348623157E+308 - -2.2250738585072014E-308,0,2.2250738585072014E-308 - 1.7976931348623157E+308
MySQL支持标准SQL语法FLOAT(P),P表示精度,当P在0-23范围时表示单精度浮点数(FLOAT),当P在24-53范围时表示双精度浮点数(DOUBLE)。
在MySQL 8.0前,MySQL支持非标准语法FLOAT(M,D)和DOUBLE(M,D),用于限制类型的存储范围,当并不影响其存储空间占用,但在MySQL 8.0开始标记弃用。
如FLOAT(5,2)限制存储数据范围在-999.99至999.99,使用4个字节空间。
浮点数(Approximate Value)
浮点数类型的实现目的是使用较小的存储空间来存放较大范围的数据。
MySQL使用4个字节32bytes来存放INT类型数据,单个byte能表示0和1两个值,能表示2的32次方个数值,使用一个byte表示正负关系,剩余31个bytes能表示2的31次方个数值,因此存储范围是-2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647)的所有整数数值。
MySQL中FLOAT的存储范围3.402823466E+38 - -1.175494351E-38,0,1.175494351E-38 - 3.402823466E+38,使用4个字节32bytes来存放,无法存储该范围内所有数值,只能存放该范围内部分点的数值。
浮点数数据分布情况:
1、越靠近零点处,数的分布越密集,能够表示的精度越高
2、越远离零点处,数的分布越稀疏,能够表示的范围约大
https://jingyan.baidu.com/article/64d05a022ea757de55f73b1d.html
FLOAT数据分布测试
CREATE TABLETB1001(
IDINT PRIMARY KEY,
C1FLOAT);INSERT INTO TB1001(ID,C1)VALUES(1,274878000000);INSERT INTO TB1001(ID,C1)VALUES(2,274877000000);INSERT INTO TB1001(ID,C1)VALUES(3,274876000000);INSERT INTO TB1001(ID,C1)VALUES(4,274876000000-1);INSERT INTO TB1001(ID,C1)VALUES(5,274875000000);SELECT * FROMTB1001;+----+--------------+
| ID | C1 |
+----+--------------+
| 1 | 274878000000 |
| 2 | 274877000000 |
| 3 | 274876000000 |
| 4 | 274876000000 |
| 5 | 274875000000 |
+----+--------------+
C1能存放274878000000的值,证明274876000000-1未达到其存储范围最大值,但插入过程中值274876000000-1被当做274876000000进行存储,由于274876000000离0点处太远,导致存储精度严重下降。
浮点数等值比较
由于浮点数存储的是近似值而非精确值,因此对浮点数做等值判断会存在问题,在MySQL中对浮点数做等于/不等于/大于等于/小于等于/GROUP BY等操作都会存在问题。