MySQL 一些让人容易忽视的知识点
一下都是MySQL在实际开发中,经常容易让人忽视的点,希望对您有帮助,帮您越过这些坑。
一:MySQL AND优先级大于OR
今天上班时在写一个业务的时候又发现了一个MySQL的问题:
我们的业务是这样的,用户可以修改自己的行数据,但这些行数据中有些数据是不能重复的,举个例子比如我们如果要开公司就要去工商局注册公司名,这时工商局可能就有一个《公司名》的表,这个表有一个主键id字段,然后有一个公司名称字段,公司英文名称字段,以及公司地点字段等等其他的数据字段,很明显这里的公司名以及公司英文名必须是唯一,因为不能有同名的公司。然后我们的业务提供给这个公司一个修改自己这条行数据的功能,比如你可以修改自己公司的中文名称或英文名称,或者地址等等,但是因为公司名是唯一的,所以在我们update数据前,我们先做了一个判断,看是否用户提交的数据中的公司名称以及英文是否已经存在,如果已经存在则告诉他,中文公司名或者是英文名已存在,请修改后重新提交。这里看似业务没有问题,但其实我们稍加测试后就发现了问题:
当用户在修改数据时只修改了中文名称或者英文名称时,此时就会有问题,比如用户想更改自己的英文公司名,因为用户提交的数据的中文名称还是原来的,所以我们在查询时发现这个中文名已经存在,所以会返回修改失败。
比如我们的判断语句是:select * from base_pop where name=$name or en-name=$en-name;只要这个查询返回结果集,就说明修改后的公司名已存在,修改失败。但是我们这里并没有考虑到局部修改的问题,甚至是如果你只想修改公司地址这种可以重复的信息,而没有更改时中英文名称时,这条SQL都会有返回集,所以都会返回修改不成功。
所以后来我们SQL更改为:select * from base_pop where name=$name or en-name=$en-name and id!=$id;这样修改后,基本上就没有问题了。已经可以完成大部分的业务需求,然而这里却引出了MySQL另外的一个问题,也就是我们今天的主题!
请看下图:
从上面这两张图中我们可以看到,当我们写:(A,B,C为三个表达式,如name=1这种),
where A and/or B and/or C; 这种where条件是有时候他的返回集和 where (A and/or B) and/or C; 的返回集一样,而有的时候又和where A and/or (B and/or C); 的返回集一样。这是什么情况呢,这里和我们设想的应该和C语言一样,自左向右运算的想法并不一样。到底MySQL自己的运算机制是自左向右还是自右向左的呢,怎么有的时候是向左有的时候是向右呢?
然而我们仔细查看后返现,会发现上面两种图有一个共性,不管是自作向右还是自右向左,我们发现返回结果集相同的SQL语句的括号总是括这包含and的语句,难道MySQL默认是先执行and语句的?
于是我们查看《MySQL手册》,得出以下结论:
我们发现,果然和我们的猜想一样,AND的操作符优先级就是比OR高,MySQL是用C语言写的,其实C语言在这里也是一样的,在C中&&的操作符优先级就是比||高,所以MySQL这里也是一样的,并不仅仅是简单的左结合性的问题。
这个在开发中也是比较常见的,有的时候会使用不至两个表达式。
二:MySQL中文乱序
今天上班,发现了一个有趣的东西,我们有一张表存的是国内运营商的资料,如id,name之类的。我们有一个业务,需要让用户选择自己对应的运营商,所以后台需要向前端返回运营商的名字以及id,name用来给用户展示,id用来记录用户选择了什么。如下图:
首先,标的结构如下:
表里的数据如下:
根据业务,我们写入了如下的SQL语句:
没想到返回的结果街竟然是这样的,为什么会是乱序的呢?为什么id和name都没有呈现出一定的顺序?
仔细看了看,我发现返回的结果集只有两个字段,这不仅让我想起了InnoDB的非聚集索引的结构,(可参看《数据库为什么要用B+数结构--MySQL索引结构的实现》),难道是因为这条SQL使用了name字段上的非聚集索引?所以主键相对无序,但是name字段也没有表现出顺序啊,但是如果我们的查询语句是这样写的,按理说应该就是使用的非聚集索引。此时我有想到哦了MyISAM的倒排索引的全文索引,的确,InnoDB的B+树索引在处理中文的时候是会有一点问题。于是我们做出如下测试:
我们先在表中插入几条测试数据,让这几条数据是英文的:
然后再执行之前的查询语句,
果不其然,这里我们新插入的a,b,c确实表现出的他应该有的顺序。
所以这里的中文应该是有序排列的,只不过没有对应拼音,这应该和中文字符的编码有关系,我们都知道gbk,utf-8等等,汉字在计算机中的存储并不是用拼音,所以没有展现出有序性,如果我们把这些汉字转换成2进制,应该就能看到他们是有序排列的。所以我们在开发中如果要有序,需要自己加上order by:
最后,我们再做一个测试,看看我们的猜想对不对,是否使用的非聚集索引:如下
首先,表中的索引有:
我们的SQL使用的索引是:
果不其然,使用的就是name字段的索引。
这个在实际开发中还是挺常见的,在InnoDB中当我们使用中文的时候,还是要多加注意。
MySQL 一些让人容易忽视的知识点的更多相关文章
- MySQL做练习时总结的一些知识点
MySQL做练习时总结的一些知识点 0:mysql有三种注释方法 上午插入记录的时候一直没有成功,郁闷不知道为什么.因为是很多条记录一起插入,中间一些不用的数据就用"--" ...
- 【Java基本功】很多人经常忽视的Java基础知识点
*.Java文件 问题:一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 答案:可以有多个类,但只能有一个public的类,并且public的类名必须与文件 ...
- 【千纸诗书】—— PHP/MySQL二手书网站后台开发之知识点记录
前言:使用PHP和MySQL开发后台管理系统的过程中,发现有一些通用的[套路小Tip],这里集中记录一下.结合工作中ing的后台业务,我逐渐体会到:除了技术知识外.能使用户体验好的“使用流程设计”积累 ...
- mysql运维必会的一些知识点整理
(1)基础笔试命令考察 1.开启MySQL服务 /etc/init.d/mysqld start service mysqld start systemctl start mysqld 2.检测端口是 ...
- mysql运维必会的一些知识点整理(转自民工哥)
(1)基础笔试命令考察 1.开启MySQL服务 /etc/init.d/mysqld start service mysqld start systemctl start mysqld 2.检测端口是 ...
- Python中容易忽视的知识点
今天坐在实验室,觉得有点无聊,想了下,很久没写博客了,就来写一点,正好遇到了一个有意思的小问题,分享给大家. 首先我们通过一个小的实验来看一下内容: 不管是 Python2 还是 Python3 环境 ...
- MySQL,必须掌握的6个知识点
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- mysql中查询语句中的一个知识点说明
1, 简单说明. select * from tb_name where 1[不为零即可];则会显示所有记录,select * from tb_name where 0;则不显示任何记录 假设数据库中 ...
- 第 10 章 MySQL Server 性能优化
前言: 本章主要通过针对MySQL Server(mysqld)相关实现机制的分析,得到一些相应的优化建议.主要涉及MySQL的安装以及相关参数设置的优化,但不包括mysqld之外的比如存储引擎相关的 ...
随机推荐
- [boostrap]debian下为arm创建debian和emdebian文件系统
转自:http://www.cnblogs.com/qiaoqiao2003/p/3738552.html Debian系统本身包含对arm的支持,其包含的软件包最多,但是最终的文件系统要大一些. e ...
- 浅谈NFC、RFID、红外、蓝牙的区别
很多朋友对NFC和RFID这两个词感到陌生,但是手机经常会出现支持NFC支付,又没太在意,NFC与RFID其实是手机支付的种方式(手机支付也被称作移动支付,是一种允许移动用户使用其移动终端对所消费的商 ...
- cookie,Session机制的本质,跨应用程序的session共享
目录:一.术语session二.HTTP协议与状态保持三.理解cookie机制四.理解session机制五.理解javax.servlet.http.HttpSession六.HttpSession常 ...
- MFC常见错误提示:opened in another editor
有时候在使用MFC的过程中常常会遇到这种提示.假设你在看想必你也遇到这种烦恼. 没办法-- 把打开的文件所有关闭.然后你就发现期待的RC文件出现了! .!!!.!!!!!!! ! !.! !! .
- erlang的汉字字符串和二进制的相互转换,并还原成汉字打印
19> Hanzi = <<"汉字"/utf8>>. <<230,177,137,229,173,151>> 20> i ...
- elasticsearch中mapping的_source和store的笔记
0.故事引入 无意中看到了ES的mapping中有store字段,作为一个ES菜鸡,有必要对这个字段进行下笔记. 1._source _source字段我在们进行检索时相当重要, ES默认检索只会返回 ...
- loadimage1();有问题
f.Read(pBuffer, nSize)不能少,少了虽然能读进去数据但是不能显示成图片,可能原因是存进的数据并不是图片数据! 输入图片测试,但是没有CFile先Open再Read
- Spark源代码阅读笔记之MetadataCleaner
MetadataCleaner执行定时任务周期性的清理元数据(metadata),有6种类型的元数据:MAP_OUTPUT_TRACKER.executor跟踪各个map任务输出的存储位置的数据,依据 ...
- Windows远程桌面没有密码的电脑
你如果想远程一个密码为空的机器,默认情况下是不可以的,需要进行以下设置 1.windows家庭版不支持远程桌面 2. 3.搜索“本地安全策略”
- Linux下的高级拾色器—Pick
导读 虽然大多数设计师都在使用 Mac,但也有一少部分在使用 Windows 甚至是 Linux 系统.在 Mac 和 Windows 中都有非常丰富的拾色器工具或插件可用,反而在开源界中这类颜色选择 ...