隐式类型转换

之前工作的时候,写错了一条sql,判断某varchar类型的字段=2,结果匹配了很多条数据,比如

select tt from table1 where tt = 2;

结果集tt中 有 “2sssss”、“2dddddd”等。当时是很好奇,后面去查阅了资料,才发现这是mysql隐式转换导致的。

那么什么是隐式转换呢?
官方对mysql的隐式转换规则描述如下:

  1. 两个参数至少有一个是null时,比较的结果也是null,例外是使用<=>对两个null做比较时会返回1,这两种情况都不需要做类型转换。
  2. 两个参数都是字符串,会按照字符串来比较,不做类型转换。
  3. 两个参数都是整数,会按照整数来比较,不做类型转换。
  4. 十六进制的值和非数字作比较时,会被当做二进制串,和数字做比较时会按下面的规则处理。
  5. 有一个参数是TIMESTAMP或DATETIME,并且另外一个参数是常量,常量会被转换为TIMESTAMP。
  6. 有一个参数是decimal类型,如果另外一个参数是decimal或者整数,将会将整数转换为decimal后进行比较,如果另外一个参数是浮点数,则会把decimal转换为浮点数进行比较。
  7. 所有其他情况下,两个参数都会被转换为浮点数再进行比较。

  在where的条件语句中,字段类型与赋予条件的数据类型不一样是,需要进行一致转换才可以比较。

  默认的转换规则是:

  • 不同类型全部转换为浮点型
  • 如果字段是字符型,条件是整型,那么会把表中的字段全都转换为整型。

总结:

  1. 字符转整型
    • 字符开头的一律为0
    • 数字开头的,直接截取到第一个不是数字的位置
  2. 时间类型转换
    • date转datetime 或者timestamp 追加 00:00:00
    • date转time 直接为00:00:00
    • datetime或者timestamp 转 date,直接截取date字段
    • datetime 或者 timestamp 转 time 直接截取 time字段
    • time 转datetime 或者timestamp 按照字符串进行截取 入 23:12:13 -> 2023-12-13;10:12:32->0000-00-00 或为空。
    • time和datetime转换为数字时,会变为双精度,加上ms。

例子:
  比如tt(varchar),如果写条件为tt=0,则会把所有的tt字段的字符全都转换成为整型,再和0去比较,再返回匹配的行。若tt字段有索引,此场景无法使用索引只能进行全表扫描,造成了慢查询的产生。

注意:
mysql的隐式类型规则较复杂,依赖mysql隐式转换很容易出现各种想象不到的问题,且隐式类型转换非常耗费mysql服务器性能,因此不推荐这样使用,因此在进行条件搜索的时候,注意使用的搜索值与字段的类型一致。

参考资料https://www.cnblogs.com/wtcl/p/9085427.html、https://blog.csdn.net/weixin_34233618/article/details/92471842、https://blog.devopszen.com/mysql_params

 

posted @ 2020-11-29 20:36  smallzhen  阅读(429)  评论(0编辑  收藏  举报