MySQL MySQL如何处理数字表达式评估过程中的溢出?

MySQL MySQL如何处理数字表达式评估过程中的溢出?

在进行数字计算的过程中,可能会出现数字溢出的情况。MySQL针对这种情况,采取了不同的处理方式。

阅读更多:MySQL 教程

MySQL的数字类型

在探究MySQL如何处理数字溢出之前,我们先来了解一下MySQL中的数字类型。

MySQL中的数字类型主要有以下几种:

  • TINYINT
  • SMALLINT
  • MEDIUMINT
  • INT
  • BIGINT
  • FLOAT
  • DOUBLE

这几种类型所占用的存储空间以及表示范围如下:

类型 存储空间 范围
TINYINT 1 字节 -128 到 127(有符号),0 到 255(无符号)
SMALLINT 2 字节 -32,768 到 32,767(有符号),0 到 65,535(无符号)
MEDIUMINT 3 字节 -8,388,608 到 8,388,607(有符号),0 到 16,777,215(无符号)
INT 4 字节 -2,147,483,648 到 2,147,483,647(有符号),0 到 4,294,967,295(无符号)
BIGINT 8 字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(有符号),0 到 18,446,744,073,709,551,615(无符号)
FLOAT 4 字节 大约 -3.40282347E+38 到 -1.17549435E-38、0 和 1.17549435E-38 到 3.40282347E+38
DOUBLE 8 字节 大约 -1.7976931348623157E+308 到 -2.2250738585072014E-308、0 和 2.2250738585072014E-308 到 1.7976931348623157E+308

这些类型在MySQL中都有其独特的应用场景。

数字溢出导致的问题

当进行数字运算时,如果计算结果超出了该数据类型所能表示的范围,就会发生数字溢出。

例如,当使用tinyint类型为a和b赋值,然后使用a + b运算时,如果结果超出了tinyint类型的范围,就会发生数字溢出,结果将是不正确的。

DECLARE a TINYINT;
DECLARE b TINYINT;

SET a = 127;
SET b = 1;

SELECT a + b;

在上面的例子中,a的值为127,b的值为1,它们的和已经超出了tinyint类型能够表示的范围。在MySQL中,数字溢出的结果是未定义的,执行上述SELECT语句将会返回-128。

MySQL的数字运算

MySQL有着相对复杂的数字运算规则。

对于数字类型为Unsigned的列,MySQL遵循以下规则:

  • 如果将一个负数插入unsigned列中,其值会被解释为无符号整数,即该值会加上2^n,其中n是数值类型的位数。例如,当一个有符号的tinyint类型的列包含值-1时,它在该列被定义为无符号类型时,将变成255。

对于数字类型为Signed的列,MySQL遵循以下规则:

  • 当两个数进行加、减、乘或一元减除操作时,MySQL会根据它们的精度和大小来选择正确的结果类型(容量越大的类型,其表示的数字范围越大)。
  • 在除法运算中,如果除数为0,则MySQL将返回NULL。如果被除数为0,则MySQL将返回0或NULL,取决于所使用的SQL_MODE。
  • 对于整数类型的数值列,如果除法结果需要小数部分,则将其转换为浮点类型来存储结果,此时将使用float或double类型,具体取决于数值列的定义和MySQL版本。

MySQL处理数字溢出的方式

在数字计算中,MySQL的处理方式取决于具体的数值类型:

  • 对于整型类型,如果计算结果的绝对值或者大小超出了该类型所能表示的范围,MySQL会截断最高位的位数,将结果保留在该类型的范围内,并发出一个警告。
  • 对于浮点型类型,如果计算结果超出了类型范围,则会返回对应的有限取值:正无穷、负无穷或NaN。

为了方便演示,下面我们将从以下两个方面来说明MySQL的数字溢出处理方式:

  1. 整型类型溢出;
  2. 浮点型类型溢出。

整型类型溢出

首先,我们来看一个整型类型溢出的例子:

DECLARE a BIGINT;
DECLARE b BIGINT;

SET a = 9223372036854775807;
SET b = 1;

SELECT a + b;

在上面的例子中,a的值为9223372036854775807,b的值为1,它们的和超出了bigint类型能够表示的范围。

在这种情况下,MySQL会截断最高位的位数,将结果保留在bigint类型的范围内,并返回一个警告。执行上述SELECT语句,将输出以下结果和警告:

+-----------------------+
| a + b                 |
+-----------------------+
| 9223372036854775808   |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect BIGINT value: '9223372036854775808'

从结果和警告中,我们可以看到MySQL将计算结果截断后保留在bigint类型的范围内,同时发出了一个警告。

浮点型类型溢出

然后,我们再来看一个浮点型类型溢出的例子:

DECLARE a FLOAT;
DECLARE b FLOAT;

SET a = 1e+307;
SET b = 1;

SELECT a * b;

在上面的例子中,a的值为1e+307,b的值为1,它们的乘积超出了float类型能够表示的范围。

在这种情况下,MySQL会返回对应的有限取值:正无穷、负无穷或NaN。执行上述SELECT语句,将输出以下结果:

+----------------------------------------------------------------+
| a * b                                                          |
+----------------------------------------------------------------+
| INF                                                            |
+----------------------------------------------------------------+
1 row in set (0.00 sec)

从结果中,我们可以看到MySQL返回了一个正无穷的值。

结论

MySQL有着相对复杂的数字运算规则,并且在数字计算过程中可能会出现数字溢出的情况。针对这种情况,MySQL采取了不同的处理方式。对于整型类型,如果计算结果超出了类型范围,将会截断最高位的位数,将结果保留在该类型的范围内,并发出一个警告;对于浮点型类型,如果计算结果超出了类型范围,将会返回对应的有限取值:正无穷、负无穷或NaN。在编写MySQL应用程序时,需要注意数字溢出可能导致的问题,并根据实际情况选择适合的数据类型。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程