一下都是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 一些让人容易忽视的知识点的更多相关文章

  1. MySQL做练习时总结的一些知识点

    MySQL做练习时总结的一些知识点     0:mysql有三种注释方法 上午插入记录的时候一直没有成功,郁闷不知道为什么.因为是很多条记录一起插入,中间一些不用的数据就用"--" ...

  2. 【Java基本功】很多人经常忽视的Java基础知识点

    *.Java文件 问题:一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 答案:可以有多个类,但只能有一个public的类,并且public的类名必须与文件 ...

  3. 【千纸诗书】—— PHP/MySQL二手书网站后台开发之知识点记录

    前言:使用PHP和MySQL开发后台管理系统的过程中,发现有一些通用的[套路小Tip],这里集中记录一下.结合工作中ing的后台业务,我逐渐体会到:除了技术知识外.能使用户体验好的“使用流程设计”积累 ...

  4. mysql运维必会的一些知识点整理

    (1)基础笔试命令考察 1.开启MySQL服务 /etc/init.d/mysqld start service mysqld start systemctl start mysqld 2.检测端口是 ...

  5. mysql运维必会的一些知识点整理(转自民工哥)

    (1)基础笔试命令考察 1.开启MySQL服务 /etc/init.d/mysqld start service mysqld start systemctl start mysqld 2.检测端口是 ...

  6. Python中容易忽视的知识点

    今天坐在实验室,觉得有点无聊,想了下,很久没写博客了,就来写一点,正好遇到了一个有意思的小问题,分享给大家. 首先我们通过一个小的实验来看一下内容: 不管是 Python2 还是 Python3 环境 ...

  7. MySQL,必须掌握的6个知识点

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  8. mysql中查询语句中的一个知识点说明

    1, 简单说明. select * from tb_name where 1[不为零即可];则会显示所有记录,select * from tb_name where 0;则不显示任何记录 假设数据库中 ...

  9. 第 10 章 MySQL Server 性能优化

    前言: 本章主要通过针对MySQL Server(mysqld)相关实现机制的分析,得到一些相应的优化建议.主要涉及MySQL的安装以及相关参数设置的优化,但不包括mysqld之外的比如存储引擎相关的 ...

随机推荐

  1. Unix系统编程()检查进程的存在

    检查进程的存在 kill系统调用还有另一重功用.若将参数sig指定为0(即所谓空信号),则无信号发送. 相反,kill仅会去执行错误检查,查看是否可以向目标进程发送信号. 从另一角度来看,这意味着,可 ...

  2. 嵌入式linux性能详解_转

    最近简单看了下<嵌入式Linux性能详解>一书,对系统内存分布测试.程序运行.动态库等都很很好的解析. 作者史子旺,loughsky@sina.com. 有时间希望仔细通读,并验证.

  3. udp program

    UDP program UDP常用函数:recvfrom和sendto recvfrom ssize_t recvfrom(int sockfd, void *buf, size_t len, int ...

  4. C++中变量做数组长度

    在Java中,这是完全可以的,比如我们运行如下程序: package cn.darrenchan.storm; import java.util.Arrays; public class Test { ...

  5. setTranslatesAutoresizingMaskIntoConstraints和setFrame组合使用导致的异常

    在用Ojbect-c开发OSX应用的时候需要用到自定义控件并用代码进行布局,很自然地就使用了setTranslatesAutoresizingMaskIntoConstraints和setFrame组 ...

  6. c经典算法

    1. 河内之塔 说明 河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时 北越的首都,即现在的胡志明市:1883年法国数学家 Ed ...

  7. ubuntu vnc安装

    VNC(Virtual Network Computing),为一种使用RFB协议的屏幕画面分享及远程操作软件.此软件借由网络,可发送键盘与鼠标的动作及即时的屏幕画面. 1. 安装vnc服务器 sud ...

  8. mybatis 的动态sql语句是基于OGNL表达式的。

    mybatis 的动态sql语句是基于OGNL表达式的.可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类:1. if 语句 (简单的条件判断)2. c ...

  9. 考虑下面两个JSP文件代码片断: test1.jsp:

    <HTML> <BODY> <% pageContext.setAttribute(”ten”,new Integer(10));%> //1 </BODY& ...

  10. 在函数体的“出口处”,对 return 语句的正确性和效率进行检查

    在函数体的“出口处”,对 return 语句的正确性和效率进行检查. 如果函数有返回值,那么函数的“出口处”是 return 语句. 我们不要轻视 return 语 句.如果 return 语句写得不 ...