- MySQL 8.0从入门到实战
- 张文亮编著
- 1732字
- 2024-12-27 21:25:55
3.1 数字数据类型
在MySQL中,数字数据类型又分为如下4个类别:
· 整数类型:integer、int、smallint、tinyint、mediumint、bigint。
· 定点类型:decimal、numeric。
· 浮点类型:float、double。
· 位值类型:bit。
1.整数类型
MySQL支持SQL标准整数类型int和smallint,也支持标准扩展的整数类型tinyint、mediumint和bigint。表3-1显示了每种整数类型所需的存储空间和取值范围,我们可以根据实际情况选用合适的整数类型。
表3-1 整数类型所需的存储空间和取值范围
2.定点类型
decimal和numeric类型用于保存对精度要求很高的数据,比如货币数据。在MySQL中,numeric被实现为decimal,所以适用于decimal数据类型的数据同样适用于numeric数据类型的数据。
在decimal列声明中,可以指定精度和小数位数。
例3.1 在decimal列声明中指定精度为5,小数位数为2,SQL语句如下:
salary decimal(5,2)
精度表示为值存储的有效位数,小数位数表示可以存储在小数点后的位数。decimal(5,2)可以用于存储具有5位数字和两位小数的任何数值,因此定义为此数据类型的salary列的取值范围为‒999.99~999.99。如果decimal小数位数为0,则值不包含小数点或小数部分,但定义为decimal数据类型的列的实际取值范围可能会受到所定义的精度或小数位数的限制。如果给定义为decimal数据类型的列分配的值的小数点后的位数超过所允许的位数,那么数值会被截断到允许的位数。表3-2是decimal数据类型的详细说明。
表3-2 decimal数据类型的详细说明
3.浮点类型
float和double数据类型表示的是浮点数据类型。在MySQL中,单精度浮点数使用4字节,双精度浮点数使用8字节。表3-3是float和double数据类型的详细说明。
表3-3 float和double数据类型的详细说明
需要注意的是,如果要使程序具有最大的可移植性,那么在定义浮点数据的类型时,应该定义为float或double precision数据类型,且不要指定精度或位数。
4.位值类型
即bit类型,它的表示方式为bit(m),m的取值范围为1~64。bit类型存储的是二进制字符串。
bit类型的数据范围为bit(1)~bit(64),换算成十进制,其值的取值范围为0~264‒1;tinyint unsigned类型的数值取值范围为0~255(十进制数)。bit类型占用的存储空间近似为(m+7)/8字节,而tinyint类型的存储空间为1字节。当使用bit(1)和tinyint时,它们占用的存储空间是一致的。
5.超出范围和溢出处理
当MySQL在数值列中存储超出列数据类型允许范围的值时,其结果取决于当时启用的SQL模式:
· 如果启用了严格的SQL模式,那么MySQL会根据SQL标准拒绝超出范围的值并显示错误提示信息,表明插入操作失败。
· 如果没有启用限制模式,那么MySQL会将插入的值截断为列数据类型范围的边界值来存储。
· 当把超出定义范围的值分配给定义为整数的列时,MySQL将把列数据类型范围的边界值存储到列中。
· 当为浮点或定点类型的列分配的值超出指定(或默认)精度和小数位数所隐含的范围时,MySQL将把列数据类型范围的边界值存储到列中。
1)超出范围处理
例3.2 假设表t1具有以下定义:
create table t1 (i1 tinyint, i2 tinyint unsigned);
(1)启用严格SQL模式后,会出现超出范围的错误。
使用如下命令启用数据库的严格SQL模式:
mysql> set sql_mode = 'traditional';
在启用数据库的严格SQL模式下,插入超过数据类型范围的数值会被拒绝插入并抛出异常:
mysql> insert into t1 (i1, i2) values(256, 256); ERROR 1264 (22003): Out of range value for column 'i1' at row 1mysql> select * FROM t1;Empty set (0.00 sec)
(2)如果未启用严格SQL模式,则会发出警告,但是不会报错。
使用如下语句设置未启用严格SQL模式:
mysql> set sql_mode = '';
如下语句是在未启用严格SQL模式的情况下插入超过数据类型范围的数值:
mysql> insert into t1 (i1, i2) values(256, 256);
如下语句是在查询上面的插入语句时出现的警告信息:
如下语句用来检验当插入的数值超出数据类型的范围时,数值是否会插入数据表中:
从结果可知,如果不启用严格SQL模式,在数值超过数据类型范围的情况下依然会把数据添加到数据表中,只不过发出了警告,同时实际插入的数值是数据类型范围的边界值,在本例中有边界,即为最大值。
2)溢出处理
数值表达式计算期间的溢出会导致错误。
例3.3 有符号bigint值的最大值是9223372036854775807,因此以下语句会产生错误:
mysql> select 9223372036854775807 + 1; ERROR 1690 (22003): bigint value is out of range in '(9223372036854775807 + 1)'
在这种情况下,要想操作成功,可以将结果值转换为无符号数。
发生溢出的原因是结果值超过了数据类型范围的上限,所以处理上面这种错误的另一种方法就是修改数值的数据类型,例如把数值类型修改为浮点类型,因为浮点类型的取值范围大,对于此例不会出现异常情况:
在默认情况下,unsigned整数值之间的减法(其中一个类型为unsigned)会产生一个无符号结果值。如果结果值是负数,则会导致错误:
mysql> set sql_mode = ''; Query OK, 0 rows affected (0.00 sec) mysql> select cast(0 as unsigned) - 1; ERROR 1690 (22003): bigint unsigned value is out of range in '(cast(0 as unsigned) - 1)'
如果no_unsigned_subtraction启用了SQL模式,则不会出现执行语句的异常: