隐式类型转换
Posted smallzhen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了隐式类型转换相关的知识,希望对你有一定的参考价值。
之前工作的时候,写错了一条sql,判断某varchar类型的字段=2,结果匹配了很多条数据,比如
select tt from table1 where tt = 2;
结果集tt中 有 “2sssss”、“2dddddd”等。当时是很好奇,后面去查阅了资料,才发现这是mysql隐式转换导致的。
那么什么是隐式转换呢?
官方对mysql的隐式转换规则描述如下:
- 两个参数至少有一个是null时,比较的结果也是null,例外是使用<=>对两个null做比较时会返回1,这两种情况都不需要做类型转换。
- 两个参数都是字符串,会按照字符串来比较,不做类型转换。
- 两个参数都是整数,会按照整数来比较,不做类型转换。
- 十六进制的值和非数字作比较是,会被当做二进制串,和数字做比较时会按下面的规则处理。
- 有一个参数是TIMESTAMP或DATETIME,并且另外一个参数是常量,常量会被转换为TIMESTAMP。
- 有一个参数是decimal类型,如果另外一个参数是decimal或者整数,将会将整数转换为decimal后进行比较,如果另外一个参数是浮点数,泽辉吧decimal转换为浮点数进行比较。
- 所有其他情况下,两个参数都会被转换为浮点数再进行比较。
在where的条件语句中,字段类型与赋予条件的数据类型不一样是,需要进行一致转换才可以比较。
默认的转换规则是:
- 不同类型全部转换为浮点型
- 如果字段是字符型,条件是整型,那么会把表中的字段全都转换为整型。
总结:
- 字符转整型
- 字符开头的一律为0
- 数字开头的,直接截取到第一个不是数字的位置
- 时间类型转换
- 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
以上是关于隐式类型转换的主要内容,如果未能解决你的问题,请参考以下文章