首页 » SEO优化 » phpmysqlvarbinary技巧_MySQL 避坑指南之隐式数据类型转换

phpmysqlvarbinary技巧_MySQL 避坑指南之隐式数据类型转换

访客 2024-12-08 0

扫一扫用手机浏览

文章目录 [+]

当两个不同类型的数据进走运算时,为了使得它们能够兼容,MySQL 可能会实行隐式的数据类型转换。
例如,MySQL 在须要时会自动将字符串转换为数字,反之亦然。

mysql> SELECT 1+'1'; -> 2mysql> SELECT CONCAT(2,' test'); -> '2 test'

我们也可利用 CAST() 函数将数字显式转换为字符串。
CONCAT() 函数中的隐式类型转换是由于它只能吸收字符串类型的参数。

phpmysqlvarbinary技巧_MySQL 避坑指南之隐式数据类型转换

mysql> SELECT 38.8, CAST(38.8 AS CHAR); -> 38.8, '38.8'mysql> SELECT 38.8, CONCAT(38.8); -> 38.8, '38.8'

以下是比较运算中的类型转换规则:

phpmysqlvarbinary技巧_MySQL 避坑指南之隐式数据类型转换
(图片来自网络侵删)

如果任意一个参数为 ,比较的结果为 ,<=> 相等比较运算符除外。
<=> 的运算结果为 true,不须要进行类型转换。

如果两个参数都是字符串,实行字符串比较。

如果两个参数都是整数,实行整数比较。

如果不是和数字进行比较,十六进制数值将被看作二进制字符串。

如果一个参数是 TIMESTAMP 或者 DATETIME 字段,另一个参数是常量,该常量将会在比较之前转换为韶光戳类型。
这一规则是为了更好地支持 ODBC 规范。
IN() 运算符中的参数不会实行这一转换。
为了保险起见,记得在实行比较运算时利用完全的日期韶光、日期或者韶光字符串。
例如,在利用 BTWEEN 运算符判断日期或者韶光数据时,利用 CAST() 函数将数据的类型显示转换成相应的类型。

返回单行结果的子查询不会被当作常量。
例如,当一个返回整数的子查询和 DATETIME 数据进行比较时,DATETIME 将会被转换为整数类型,而不会将子查询的结果转换为韶光类型。
如果想要实行日期韶光比较,可以利用 CAST() 函数显式将子查询的结果转换为 DATETIME 类型。

如果一个参数为精确数字类型(decimal),比较的方法取决于另一个参数的类型。
如果另一个参数是精确数字或者整数类型,利用精确数字比较;如果另一个参数是浮点数类型,利用浮点数比较。

其他情形下,利用浮点数比较。
例如,字符串和精确数字的比较利用浮点数比较方法。

关于韶光类型之间的转换规则,可以参考官方文档。

以下示例演示了将字符串转换为数字的比较操作:

mysql> SELECT 1 > '6x'; -> 0mysql> SELECT 7 > '6x'; -> 1mysql> SELECT 0 > 'x6'; -> 0mysql> SELECT 0 = 'x6'; -> 1

如果将字符串类型的字段和数字进行比较,MySQL 无法利用该字段上的索引快速查找数据。
例如,str_col 是一个索引字段,该索引无法用于以下语句:

SELECT FROM tbl_name WHERE str_col=1;

问题的缘故原由在于很多不同的字符串都可以转换为数字 1,例如’1’、’ 1’ 或者 ‘1a’。

浮点数和 INTEGER 类型的超大数值之间的比较是近似比较,由于整数在比较之前须要转换为双精度浮点数,双精度浮点数无法精确地表示所有的 64 位整数。
例如,整数 253 + 1 无法利用浮点数进行表示,只能近似为 253 或者 253 + 2。

举例来说,以下只有第一个比较运算中的两个值相等,但是两个比较运算都返回了 true(1):

mysql> SELECT '9223372036854775807' = 9223372036854775807; -> 1mysql> SELECT '9223372036854775807' = 9223372036854775806; -> 1

字符串转换为浮点数与整数转换为浮点数的办法可能不同。
整数可能利用 CPU 转换为浮点数,而字符串可能利用浮点数乘法进行逐位转换。
其余,转换结果可能受到各种成分的影响,例如打算机的架构、编译器版本或者优化级别等。
避免这种问题的方法之一便是利用 CAST() 函数,这样数据就不会被隐式转换为浮点数。

mysql> SELECT CAST('9223372036854775807' AS UNSIGNED) = 9223372036854775806; -> 0

关于浮点数比较的更多信息,可以参考官方文档。

MySQL 做事器供应了一个转换库 dtoa,可以支持字符串或者 DECIMAL 数据和近似数字(FLOAT/DOUBLE)之间的基本转换功能:

跨平台的同等性转换结果,例如,可以肃清 Unix 和 Windows 之间的差异。

可以精确表示之前无法供应足够精度的数据,例如靠近 IEEE 限定的数据。

以尽可能高的精度将数字转换成字符串格式。
dtoa 的精度总是即是或者高于标准 C 代码库函数。

数字或者韶光类型到字符串的隐式转换结果的字符集和排序规则取决于 character_set_connection 和 collation_connection 系统变量。
(这些变量常日利用 SET NAMES 进行设置。
关于连接的字符集的信息,可以参考官方文档。

这意味着这种转换的结果是一个非二进制的字符串(CHAR、VARCHAR 或者 LONGTEXT),除非连接字符集被设置为 binary。
此时,转换结果是一个二进制字符串(BINARY、VARBINARY 或者 LONGBLOB)。

对付整数类型的表达式,前文所述的表达式求值和表达式赋值有所不同。
例如以下语句:

CREATE TABLE t SELECT integer_expr;

这种情形下,表 t 的字段类型取决于整数表达式的长度,可能是 INT 或者 BIGINT。
如果表达式的最大长度超过了 INT,利用 BIGINT 类型。
这就意味着我们可以通过一个足够长的表达式创建 BIGINT 类型的字段:

CREATE TABLE t SELECT 000000000000000000000 AS col;DESC t;Field|Type ||Key|Default|Extra|-----+------+----+---+-------+-----+col |bigint|NO | |0 | |

JSON 数据的比较分为两种情形。
第一层次的比较基于被比较数据的 JSON 类型,如果两个类型不同,比较的结果取决于具有更高优先级的类型;如果两个数据的 JSON 类型相同,利用详细的类型规则进行第二层次的比较。
对付 JSON 和非 JSON 数据的比较,先将非 JSON 数据转换为 JSON 类型,然后进行比较。
详细信息可以参考官方文档。

作者简介:不剪发的 Tony 老师,CSDN 博客专家,CSDN 学院签约讲师, GitChat 专栏作者。
十余年数据库管理与开拓履历。
目前在一家环球性的游戏公司从事数据库架构设计和开拓事情,善于各种数据库管理与 SQL 开拓,拥有Oracle OCP 和 Redhat RHCE 证书。

标签:

相关文章

php中gmdate技巧_PHP 5 DateTime 函数

Date/Time 函数许可您从 PHP 脚本运行的做事器上获取日期和韶光。您可以利用 Date/Time 函数通过不同的办法来格...

SEO优化 2024-12-10 阅读0 评论0