文档章节

MySQL 隐式转换的前世今生

IT--小哥
 IT--小哥
发布于 2017/07/18 18:12
字数 980
阅读 16
收藏 0

前言:MySQL的隐式转换是什么样子的,什么时候会进行隐式转换,下面让我们来掀开MySQL隐式转换的面纱,下面我们通过一个例子来进行说明

 

隐式转换的几种情况:

1、当不同类型的字段一起使用时,会发生隐式转换

root@localhost:mysql.sock  16:18:23 [tom]>SELECT 1+'1';
+-------+
| 1+'1' |
+-------+
|     2 |
+-------+
1 row in set (0.00 sec)

root@localhost:mysql.sock  16:18:26 [tom]>SELECT CONCAT(2,' test');
+-------------------+
| CONCAT(2,' test') |
+-------------------+
| 2 test            |
+-------------------+
1 row in set (0.00 sec)

或者使用函数显示或者隐式进行转换

root@localhost:mysql.sock  16:29:39 [tom]>SELECT 38.8, CAST(38.8 AS CHAR);
+------+--------------------+
| 38.8 | CAST(38.8 AS CHAR) |
+------+--------------------+
| 38.8 | 38.8               |
+------+--------------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock  16:30:27 [tom]>SELECT 38.8, CONCAT(38.8);
+------+--------------+
| 38.8 | CONCAT(38.8) |
+------+--------------+
| 38.8 | 38.8         |
+------+--------------+
1 row in set (0.00 sec)

2、下面是一些会发生隐式转换的规则

1、If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe <=> equality comparison operator. For NULL <=> NULL, the result is true. No conversion is needed.
2、If both arguments in a comparison operation are strings, they are compared as strings.
3、If both arguments are integers, they are compared as integers.
4、Hexadecimal values are treated as binary strings if not compared to a number.
5、If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. Note that this is not done for the arguments to IN()! To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type.

A single-row subquery from a table or tables is not considered a constant. For example, if a subquery returns an integer to be compared to a DATETIME value, the comparison is done as two integers. The integer is not converted to a temporal value. To compare the operands as DATETIME values, use CAST() to explicitly convert the subquery value to DATETIME.
6、If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.
7、In all other cases, the arguments are compared as floating-point (real) numbers.

3、下面是字符串转换成数字进行比较的

root@localhost:mysql.sock  17:23:38 [tom]>SELECT 1 > '6x';
+----------+
| 1 > '6x' |
+----------+
|        0 |
+----------+
1 row in set, 1 warning (0.00 sec)

root@localhost:mysql.sock  17:23:41 [tom]>SELECT 7 > '6x';
+----------+
| 7 > '6x' |
+----------+
|        1 |
+----------+
1 row in set, 1 warning (0.01 sec)

root@localhost:mysql.sock  17:23:48 [tom]>SELECT 0 > 'x6';
+----------+
| 0 > 'x6' |
+----------+
|        0 |
+----------+
1 row in set, 1 warning (0.00 sec)

root@localhost:mysql.sock  17:23:55 [tom]>SELECT 0 = 'x6';
+----------+
| 0 = 'x6' |
+----------+
|        1 |
+----------+
1 row in set, 1 warning (0.00 sec)

4、如果在sql中对一个字符串和数字比较,mysql不会使用索引

root@localhost:mysql.sock  17:24:03 [tom]>explain select * from test where name = 1;;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test  | NULL       | ALL  | name          | NULL | NULL    | NULL |    9 |    11.11 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 3 warnings (0.00 sec)

ERROR: 
No query specified

root@localhost:mysql.sock  17:25:42 [tom]>show create table test;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                               |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test  | CREATE TABLE `test` (
  `id` int(11) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `name` varchar(4) NOT NULL DEFAULT 'tom',
  KEY `name` (`name`),
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

The reason for this is that there are many different strings that may convert to the value1, such as‘1’,‘ 1’, or ‘1a’

5、浮点数的比较是近似值,可能导致结果不准确,可能会有取舍

root@localhost:mysql.sock  17:30:19 [tom]>SELECT '18015376320243459'+0.0;
+-------------------------+
| '18015376320243459'+0.0 |
+-------------------------+
|    1.801537632024346e16 |
+-------------------------+
1 row in set (0.00 sec)

浮点数与整数之间的转换,或者符号之间的转换最好使用函数CAST(),避免隐式转换

 

总结:

1、sql中的where条件禁止进行不同字段类型的比较

2、字符串类型和数字比较会转换成0然后进行比较

3、字符串转换成数字的时候是从最左边开始的(不是数字就是0,是数字就匹配最左数字,这就导致可能会多查询或者删除、更新数据,这个结果就比较悲催了)

 

参考文章:

https://dev.mysql.com/doc/refman/5.7/en/type-conversion.html 

为了方便大家交流,本人开通了微信公众号,和QQ群291519319。喜欢技术的一起来交流吧

© 著作权归作者所有

IT--小哥
粉丝 47
博文 147
码字总数 150342
作品 0
东城
数据库管理员
私信 提问
席慕容:回 眸

前世,我频频回眸 挥别的手帕飘成一朵云 多少相思多少离愁 终成一道水痕送我远走 今生, 我寻觅前世失落的足迹 跋山涉水走进你的眼中 前世的五百次回眸 换得今生的一次擦肩而过 我用一千次回...

陌尘_9353
2017/12/24
0
0
吴章金: Ftrace 实现原理与开发实践

12月10日,50几位广州的Linuxer在广州心田庄园举行了Linux workshop。四大主题演讲,蜗窝大侠郭健主持。 这是吴章金老师的演讲slides。 吴章金老师激情演讲中: 往期精选 陈莉君教授: 回望踏...

jus3ve
2017/12/14
0
0
周立功:“芯片—终端—云”生态系统

12月10日,50几位广州的Linuxer在广州心田庄园举行了Linux workshop。四大主题演讲,蜗窝大侠郭健主持。 这是周立功老师的演讲slides。 周立功老师激情演讲中: 往期精选 陈莉君教授: 回望踏...

jus3ve
2017/12/13
0
0
宋宝华: Linux系统性能剖析的模型和方法

12月10日,50几位广州的Linuxer在广州心田庄园举行了Linux workshop。四大主题演讲,蜗窝大侠郭健主持。 这是宋宝华老师的演讲slides。 广州Linuxer workshop活动影像: 往期精选 让天堂的归...

jus3ve
2017/12/19
0
0
陈莉君: Linux内核的那些书

12月10日,50几位广州的Linuxer在广州心田庄园举行了Linux workshop。四大主题演讲,蜗窝大侠郭健主持。 这是陈莉君老师的演讲slides。 处处逢归路 头头达故乡 本来成现事 何必待思量 为学患...

jus3ve
2017/12/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
今天
2K
14
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
今天
38
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
40
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
61
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
20
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部