购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.1 数值类型

数值类型主要用来存储数字,不同的数值类型提供不同的取值范围,可以存储的值范围越大,所需的存储空间也越大。MySQL支持所有标准SQL中的数值类型,其中包括严格数据类型(INTEGER、SMALLINT、DECIMAL、NUMERIC)和近似数值类型(FLOAT、REAL、DOUBLE PRECISION)。MySQL还扩展了TINYINT、MEDIUMINT和BIGINT等3种不同长度的整数类型,并增加了BIT类型,用来存储位数据。

对于MySQL中的数值类型,还要做如下说明。

· 关键字INT是INTEGER的同义词。

· 关键字DEC和FIXED是DECIMAL的同义词。

· NUMERIC和DECIMAL类型被视为相同的数据类型。

· DOUBLE可视为DOUBLE PRECISION的同义词,并在REAL_AS_FLOAT SQL模式未启用的情况下,将REAL也视为DOUBLE PRECISION的同义词。关于SQL模式请关注本书的姊妹篇《剑指MySQL——架构、调优与运维》。

5.1.1 整数类型

MySQL提供的整数类型有TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)和BIGINT。不同的整数类型有不同的取值范围,因为不同类型的整数存储所需的字节数(内存大小)是不同的,如果超出类型范围的操作,则会发生“Out of range”的错误提示。所以,在选择数据类型时要根据应用的实际情况确定其取值范围,然后选择对应的数据类型。不同整数类型存储范围如表5-1所示。

表5-1 MySQL中的整数类型说明

例如,下面演示整数类型的存储范围问题,SQL语句示例如下。

(1)创建临时表“t1_int”,有“num1”和“num2”两个字段,分别指定其数据类型为“TINYINT”和“INT”。

(2)查看“t1_int”表结构。

(3)添加一条记录,“num1”和“num2”字段分别赋值为“1”,可以发现格式没有异常。

(4)添加一条记录,“num1”和“num2”字段分别赋值为“130”,发现因为“num1”字段数据值超出范围而报“Out of range”错误。

(5)查看结果,只有一条记录插入成功。

对于整数类型,MySQL还支持在类型名称后面加小括号(M),而小括号中的M表示显示宽度,M的取值范围是(0,255)。例如int(5)表示当数据宽度小于5位的时候在数字前面需要用字符填满宽度。int类型默认显示宽度为int(11),无符号int类型默认显示宽度为int(10)。该项功能需要配合“ZEROFILL”使用,表示用“0”填满宽度,否则指定显示宽度无效。如果一个列指定为“ZEROFILL”,则MySQL自动为该列添加“UNSIGNED(无符号)”属性,即只能是正数。读者可能会问,设置了显示宽度,如果插入的数据宽度超过显示宽度限制,会不会截断或插入失败?答案是,不会对插入的数据有任何影响,还是按照类型的实际宽度进行保存,即显示宽度与类型可以存储的值范围无关。从MySQL 8.0.17开始,整数数据类型不推荐使用显示宽度属性。

例如,以下例子演示指定显示宽度问题,SQL语句示例如下。

(1)创建临时表“t2_int”,有“num1,num2和num3”3个字段,数据类型分别设置为“INT、INT(3)、INT(3)”,并给前面两个字段指定“ZEROFILL”。

(2)查看“t2_int”表结构,发现第一个字段默认显示宽度为“10”,第三个字段指定宽度无效,因为第三个字段没有加“ZEROFILL”属性,前面两个字段还自动添加了“UNSIGNED(无符号)”属性。

(3)添加一条记录,所有字段值都是1,可以发现格式没有异常。

(4)查询结果可以发现,前面两个字段在数值前面用字符“0”填充了剩余的宽度,第三个字段的数据值前面没有0填充。

(5)添加一条记录,所有字段值都是“1314”,可以发现格式没有异常。

(6)查询结果可以发现,“num2”字段按照实际的宽度存储。

5.1.2 浮点数和定点数类型

MySQL中使用浮点数和定点数来表示小数。浮点数有两种类型:单精度浮点数(FLOAT)和双精度浮点数(DOUBLE),定点数只有DECIMAL。浮点数和定点数都可以用(M,D)来表示。

· M是精度,表示该值总共显示M位,包括整数位和小数位,对于FLOAT和DOUBLE类型来说,M的取值范围为0~255,而对于DECIMAL来说,M的取值范围为0~65。

· D是标度,表示小数的位数,取值范围为0~30,同时必须<=M。

浮点型FLOAT(M,D)和DOUBLE(M,D)是非标准用法,如果考虑数据库迁移,则最好不要使用,而且从MySQL 8.0.17开始,FLOAT(M,D)和DOUBLE(M,D)用法在官方文档中已经明确不推荐使用,将来可能被移除。另外,关于浮点型FLOAT和DOUBLE的UNSIGNED也不推荐使用了,将来也可能被移除。FLOAT和DOUBLE类型在不指定(M,D)时,默认会按照实际的精度来显示。DECIMAL类型在不指定(M,D)时,默认为(10,0),即只保留整数部分。例如,定义DECIMAL(5,2)的类型,表示该列取值范围是-999.99~999.99。如果用户插入数据的小数部分位数超过D位,MySQL会做四舍五入处理,但是如果用户插入数据的整数部分位数超过“M-D”位,则会报“Out of range”的错误。

DECIMAL实际是以字符串形式存放的,在对精度要求比较高的时候(如货币、科学数据等)使用DECIMAL类型会比较好。浮点数相对于定点数的优点是在长度一定的情况下,浮点数能够表示更大的数据范围,它的缺点是会引起精度问题。不同小数类型存储范围说明如表5-2所示。

表5-2 MySQL中的小数类型存储范围说明

例如,以下例子演示浮点型FLOAT的数据插入和显示问题,SQL语句示例如下。

(1)创建临时表“t3_float”,字段“num1和num2”的数据类型分别为“FLOAT、FLOAT(15,2)”。

(2)查看表结构。

(3)插入第一条记录,所有字段值为“123.56”,可以发现格式没有异常。

(4)查询结果显示数据插入正常。

(5)插入第二条记录,所有字段值为“1234567891234.56789”,可以发现格式没有异常。

(6)查询结果发现两个字段的值都做了近似处理,因为FLOAT类型是近似数值类型。如果没有指定(M,D)的话,FLOAT类型默认有效位大约是6位,DOUBLE默认有效位大约是17位(实际精度受具体的硬件和操作系统影响)。

(7)插入第三条记录,所有字段值为“1234567891234567.56789”,整数部分的位数超过“M-D”位,即“15-2=13”位,就会报“Out of range”错误。

例如,以下例子演示定点型DECIMAL的数据插入和显示问题,SQL语句示例如下。

(1)创建临时表“t3_decimal”,字段“num1和num2”的数据类型分别为“DECIMAL、DECIMAL(20,2)”。

(2)查看表结构可以发现,num1的DECIMAL类型默认按照DECIMAL(10,0)处理。

(3)插入第一条记录,所有字段值都为“123.56”。此时发现,虽然数据插入成功,但是出现了一个warning(警告)。

(4)查看警告信息,发现是因为“num1”字段的值被截断了。

(5)查询结果发现“num1”字段只保留了整数部分,并做了四舍五入处理,刚才的警告就是因为它。

(6)插入第二条记录,所有字段值都为“1234567891234.56789”。整数部分的位数超过“M-D”位,即“15-2=13”位,就会报“Out of range”错误。

(7)插入第三条记录,字段值分别为“123.56”“123456789123456789.56789”。此时发现,虽然数据都插入精确,但是系统出现了一个警告。

(8)查询结果可以看出num2字段仍然可以精确表示相应位数的整数精度。但是小数点部分超过了2位,会自动做四舍五入处理,刚才的警告信息就是因为它。

(9)查看警告信息,发现是因为“num2”字段的值被截断了。

5.1.3 位类型

对于BIT(位)类型,用于存放位字段值,BIT(M)可以用来存放多位二进制值,M的范围从1到64,如果不写(M)则默认是1位。对于位类型字段,之前版本直接使用SELECT语句将不会看到结果,而在MySQL 8.0版本中默认以“0X”开头的十六进制形式显示,可以通过BIN()函数显示为二进制格式。

例如,以下演示BIT类型的数据插入和显示问题,SQL语句示例如下。

(1)创建临时表“t4_bit”,字段num1为BIT类型,字段num2为BIT(5)类型。

(2)查看“t4_bit”表结构,发现num1字段自动按照BIT(1)处理。

(3)插入第一条记录,字段值都是“1”。

(4)查询结果如下。

(5)插入第二条记录,字段值都是“17”。发现插入失败,报“Data too long”的错误提示,因为十进制“17”的二进制是“10001”,而“num1”的类型是“BIT(1)”,超过1位了。

(6)插入第三条记录,字段值分别是“0”和“17”。

(7)查询结果如下。

(8)使用BIN()函数查询结果如下。 +lE/Euk8a4YGgRxMC1/jqezZaZnZtBPjUl6oZccTzsf8x/FO/ModXs9gVtNijCxe

点击中间区域
呼出菜单
上一章
目录
下一章
×