MySQL隐式转换

MySQL 隐式转换

前言

你是否曾经碰到过一个查询为什么有两条记录,其中一条记录并不符合条件

例:

1
select * from tablea where xxno = 170325171202362928;

xxno170325171202362928170325171202362930 都会出现在结果中。

一个等值查询为什么会有另外一个不同值的记录查询出来呢?

分析

查询该表结构可以发现 xxnovarchar 类型,但是等号右边是一个数值类型。

这种情况下触发了MySQL的隐式转换。

也就是说它会将等式两边转换成浮点数来计算。

结论

因此,MySQL遇到字段类型不匹配的时候会进行各种隐式转换,一定要小心,可能会导致精度丢失。

MySQL 隐式类型转换规则比较复杂,依赖 MySQL 隐式转换很容易出现各种意想不到的问题。

MySQL 隐式转换本身也是非常耗费 MySQL 服务器性能,所以非常不推荐这样使用。(命中不到索引)

注意一个安全问题:假如 password 字段为字符串,查询条件为 int 0 则会匹配上。

转换规则

  • 两个参数至少有一个是 NULL 时,比较的结果也是 NULL 。例外的是,使用 <=> 对两个 NULL 做比较时会返回 1

  • 两个参数都是字符串,会按照字符串来做比较,不做类型转换

  • 两个参数都是整数,按照整数来比较,不做类型转换

  • 十六进制的值和非数字做比较时,会被当做二进制串

  • 十六进制的值和数字做比较时,数字会被转成十六进制

  • 有一个参数是 TIMESTAMPDATETIME, 并且另外一个参数是常量,常量会被转换为 TIMESTAMP

  • 有一个参数是 decimal 类型,如果另外一个参数是整数,会把整数转成 decimal

  • 有一个参数是 decimal 类型,如果另外一个参数是浮点数,会把 decimal 转为浮点数

  • 其他情况下,两个参数都会被转成浮点数再进行比较

可以通过 EXPLAIN 和 show warning 查看原因。

感谢您的阅读,本文由 Double-c 版权所有。如若转载,请注明出处:Double-c(https://double-c.github.io/2019/06/20/mysql-transformer/
my-vps-install
code-life