mysql中的隐式类型转化及实际mysql说明
Posted 安然_随心
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql中的隐式类型转化及实际mysql说明相关的知识,希望对你有一定的参考价值。
文章目录
当在不同类型的值之间比较时,mysql 就会进行类型隐式转化。另外,你也可以主动使用类型转化函数,来进行显示类型转化。主要参考文献:https://dev.mysql.com/doc/refman/8.0/en/type-conversion.html
类型转化初步认识
首先我们先来看看比较常见两种的类型转化:
- 表中列的类型为 int , 条件是string;
- 表中列的类型为 string , 条件是int;
表中列的类型为 int , 条件是string
如果数据库表中目标列的类型为int, 条件是string, 则mysql 会将 条件值转化成 数字,然后在进行比较。
举例说明
测试表结构:
CREATE TABLE `test_ld` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`creator_id` int(11) DEFAULT NULL,
`request_id` varchar(11) DEFAULT NULL,
`topic` varchar(30) DEFAULT NULL,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
`modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录修改时间',
PRIMARY KEY (`id`),
KEY `idx_creator_id` (`creator_id`),
KEY `idx_request_id` (`request_id`),
KEY `idx_topic` (`topic`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8mb4 COMMENT='测试表';
表中数据结构:
执行查询:
select id, creator_id from test_ld where creator_id='1a2';
结果:
mysql 会直接将 ‘1a2’ 转化成 数字1(将非数字后的部分直接丢弃),然后进行比较。我们可以看看这个sql 的执行计划,还是使用到了idx_creator_id 这个索引的。
当使用 select * 时,还是走的索引(这里注意,后面还是会进行比较)
表中列的类型为 string , 条件是int
测试表结构同上,topic 列为字符串类型。
表中数据如下所示:
当对字符串类型的列进行比较时,会进行前缀比较(看上去效果是进行前缀比较,实际是 mysql 会转化成 浮点数的比较。1_test 转化成浮点数,就是 等于1,去掉后面的非数字字符);
看看执行计划:
当使用 select 选择只需要索引相关列时,还是可以走索引进行比较,但是ref 是空,因为最后匹配的值可能是 9223372036854775806a ,或者9223372036854775806XXXX 等,这个是不确定的
但是当使用select * 的样式是,mysql 就不使用索引了。本来mysql 就不确定 具体的值是,不知道有多少索引满足条件,而且select * 还需要回表,所以mysql 觉得还不如全表块。
上述的select * 和这种等价,都是需要回表的
对比一下,可以完全直接匹配索引的,输入参数是string, 列也是string 的,还是优先走索引(普通的、符合常识的case)
explain select * from test_ld where topic='9223372036854775806';
隐式类型转化过程的坑
对字符串类型 执行查询,使用 int 类型参数方面的
关于int 0
执行如下sql :
select id,`topic` from test_ld where topic=0;
关于超长串
对于列是字符串类型,传入 int 类型的参数,mysql 会将 db 中的数据列的值 和输入的值 都转化成浮点数进行比较。但是 超大的数字 转化成浮点数时是不准确的。
select * from test_ld where topic=9223372036854775806;
mysql 隐式类型转化规则
-
两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=> 对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换
-
两个参数都是字符串,会按照字符串来比较,不做类型转换
-
两个参数都是整数,按照整数来比较,不做类型转换
-
十六进制的值和非数字做比较时,会被当做二进制串
-
有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为 timestamp
-
有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数,会将整数转换为 decimal 后进行比较,如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较
-
所有其他情况下,两个参数都会被转换为浮点数再进行比较
以上是关于mysql中的隐式类型转化及实际mysql说明的主要内容,如果未能解决你的问题,请参考以下文章