MySQL隐式转换
MySQL 隐式转换
前言
你是否曾经碰到过一个查询为什么有两条记录,其中一条记录并不符合条件。
例:
1 | select * from tablea where xxno = 170325171202362928; |
xxno
为 170325171202362928
和 170325171202362930
都会出现在结果中。
一个等值查询为什么会有另外一个不同值的记录查询出来呢?
分析
查询该表结构可以发现 xxno
为 varchar
类型,但是等号右边是一个数值类型。
这种情况下触发了MySQL的隐式转换。
也就是说它会将等式两边转换成浮点数来计算。
结论
因此,MySQL遇到字段类型不匹配的时候会进行各种隐式转换,一定要小心,可能会导致精度丢失。
MySQL 隐式类型转换规则比较复杂,依赖 MySQL 隐式转换很容易出现各种意想不到的问题。
MySQL 隐式转换本身也是非常耗费 MySQL 服务器性能,所以非常不推荐这样使用。(命中不到索引)
注意一个安全问题:假如 password 字段为字符串,查询条件为 int 0 则会匹配上。
转换规则
两个参数至少有一个是
NULL
时,比较的结果也是NULL
。例外的是,使用<=>
对两个NULL
做比较时会返回 1两个参数都是字符串,会按照字符串来做比较,不做类型转换
两个参数都是整数,按照整数来比较,不做类型转换
十六进制的值和非数字做比较时,会被当做二进制串
十六进制的值和数字做比较时,数字会被转成十六进制
有一个参数是
TIMESTAMP
和DATETIME
, 并且另外一个参数是常量,常量会被转换为TIMESTAMP
有一个参数是
decimal
类型,如果另外一个参数是整数,会把整数转成decimal
有一个参数是
decimal
类型,如果另外一个参数是浮点数,会把decimal
转为浮点数其他情况下,两个参数都会被转成浮点数再进行比较
可以通过 EXPLAIN 和
show warning
查看原因。