• MySQL中对隐式类型转化的定义

  当操作符与不同类型的操作数一起使用的时候,会发生类型转换以使操作数兼容。

  

mysql的隐式锁跟显示锁 mysql隐式类型转换_类型转换

 

  

mysql的隐式锁跟显示锁 mysql隐式类型转换_MySQL_02

 

  

mysql的隐式锁跟显示锁 mysql隐式类型转换_MySQL_03

 

 

mysql的隐式锁跟显示锁 mysql隐式类型转换_MySQL_04

 

 

mysql的隐式锁跟显示锁 mysql隐式类型转换_类型转换_05

 

 

mysql的隐式锁跟显示锁 mysql隐式类型转换_MySQL_06

 

 

mysql的隐式锁跟显示锁 mysql隐式类型转换_类型转换_07

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

mysql的隐式锁跟显示锁 mysql隐式类型转换_MySQL_08

 

 

浮点数比较规则

  • MySQL 里使用了这个转换类库来实现字符跟浮点数的相互转换,一是提高了浮点数的精度(相比标准库), 二是保持平台一致性。
  • 在里浮点数之间的比较是近似的。因为里浮点数是不精确的,它的精度位只有比特,大于比特的位被“四舍五入”。这会导致一些违反直观的结果。

mysql的隐式锁跟显示锁 mysql隐式类型转换_MySQL_09

 

 

二进制数据

  • 2203020330391002199===>1111010010010101100110101000110000001111010110101110001010111
  • 2203020330391002196===>1111010010010101100110101000110000001111010110101110001010100
  • 2203020330391002203===>1111010010010101100110101000110000001111010110101110001011011

mysql的隐式锁跟显示锁 mysql隐式类型转换_浮点数_10

 

 

  • 1111010010010101100110101000110000001111010110101110000000000 ====》 2203020330391002112

例外的情况

mysql的隐式锁跟显示锁 mysql隐式类型转换_mysql的隐式锁跟显示锁_11

 

 

mysql的隐式锁跟显示锁 mysql隐式类型转换_MySQL_12

 

 

原因:

  • 在执行的阶段,在设置比较方法之前,满足一些条件的情况下会做一次类型转换

mysql的隐式锁跟显示锁 mysql隐式类型转换_浮点数_13

 

 

  • 大体意思是把常量对象(表达式或者字符串)转换成整数并替换,此方法只有在比较不同的日期格式和比较跟字符串时才有效。注意上面括号中的这句 in which case strings are converted to bigints
  • 上面的转换规则并没有覆盖所有的情况,或者说一些情况在比较之前做了优化,比如此处的查询,已经不在是数字跟字符串比较了。
  • 参考 https://xiaomi-info.github.io/2019/12/24/mysql-implicit-conversion/

总结

  • 避免发生隐式类型转换,隐式转换的类型主要有字段类型不一致、in 参数包含多个类型、字符集类型或校对规则不一致等

  • 隐式类型转换可能导致无法使用索引、查询结果不准确等,因此在使用时必须仔细甄别

  • 数字类型的建议在字段定义时就定义为或者,表关联时关联字段必须保持类型、字符集、校对规则都一致