MySQL学习-数据类型-浮点,定点数,位类型

178 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

前言

上篇我们学习了MySQL中的数据类型中的整数。有兴趣的小伙伴可以阅读(# MySQL学习-数据类型-整数)。
下面学习MySQL中的数据类型中的浮点数,定点数类型与位类型。

浮点数类型

类型介绍

浮点数可以处理小数,可以把整数看成小数的一个特例。因此,浮点数的使用场景,比整数大。MySQL支持的浮点数类型,分别是FLOAT、DOUBLE、REAL。

  • FLOAT:表示单精度浮点数。占用字节数少,取值范围小。
  • DOUBLE:表示双精度浮点数。占用字节数多,取值范围大。
类型有符号数取值范围无符号数取值范围占用字节数
FLOAT(-3.402823466E+38, -1.175494351E-38),
0, (1.175494351E-38, 3.402823466E+38)
0, (1.175494351E-38, 3.402823466E+38)4
DOUBLE(-1.7976931348623157E+308, -2.2250738585072014E-308),
0, (2.2250738585072014E-308, 1.7976931348623157E+308)
0, (2.2250738585072014E-308, 1.7976931348623157E+308)8
  • REAL默认就是DOUBLE。如果把SQL模式设定为启用“REAL_AS_FLOAT”,则MySQL就认为REAL是FLOAT。如果要启用“REAL_AS_FLOAT”,可以通过以下SQL语句实现:
SET sql_mode = "REAL_AS_FLOAT";

精度误差说明

浮点数类型有个缺陷,不精准。下面设计一个表,有f1这个字段,插入值分别为0.47,0.44,0.19,运行SUM函数,我们期待的运行结果是:0.47+0.44+0.19 = 1.1。但是实际运行结果是1.0999999999999999。虽然误差很小,但确实存在误差。为什么会存在误差?问题出在MySQL对浮点类型数据的存储方式上。

MySQL用4个字节存储FLOAT类型数据,用8个字节存储DOUBLE类型数据。无论哪个,都是采用二进制的方式来进行存储的。比如9.625,用二进制,就是1001.101,或者是1.001101*2^3。如果尾数不是0或者5(比如9.264),就无法用一个二进制来精确表达。进而,就只好在取值允许的范围内进行四舍五入。

在实际开发中,如果使用浮点数,需要特别注意误差问题。因为浮点数是不准确的,所以我们要避免使用"="来判断两个数是否相等。同时,在一些对精确度要求较高的项目中,千万不要使用浮点数,不然会导致结果错误,甚至造成不可挽回的损失。那么,MySQL有没有精准的数据类型呢?是有的,就是定点数类型:DECIMAL。

定点数类型

类型介绍

  • MySQL中的定点数类型只有DECIMAL一种类型。
数据类型字节数含义
DECIMAL(M,D),DEC,NUMERICM+2字节有效范围由M和D决定

使用DECIMAL(M,D)的方式表示高精度小数。其中,M被称为精度,D被称为标度。

  • DECIMAL(M,D)的最大取值范围与DOUBLE类型一样,但是有效的数据范围是由M和D决定的。DECIMAL的存储空间并不是固定的,由精度值M决定,总共占用的存储空间为M+2个字节。也就是说,在一些对精度要求不高的场景下,比起占用同样字节长度的定点数,浮点数表达的数值范围可以更大一些。
  • 定点数在MySQL内部是以字符串的形式进行存储的,这就决定了它一定是精准的。
  • 当DECIMAL类型不知道精度和标度时,默认为DECIMAL(10,0)。当数据的精度超出了定点数类型的精度范围时,则MySQL同样会进行四舍五入处理。

位类型

类型介绍

BIT类型中存储的二进制值,类似010110。

二进制字符串类型长度长度范围占用空间
BIT(M)M1<=M<=64约为(M + 7)/8个字节

BIT类型,如果没有指定M,默认1位。表示只能存1位的二进制值。这里的M表示二进制的位数,位数最小值为1,最大值为64。插入数据时,需要注意确保插入的数据在BIT类型支持的范围内。

使用SELECT查询位字段时,可以用BIN或HEX函数进行读取。或者使用b+0查询,可以直接查询出存储的十进制数据的值。

今天先学习到这里,明天继续。