对于数据库的学习前前后后已经持续了很多年,期间主要集中在对于MySQL的学习,也穿插着做过几个与MySQL相关的项目。关于数据库的理论部分,离开书本一段时间就忘得差不多了,趁最近准备找工作,复习一下相关的理论知识。本文主要介绍MySQL的逻辑查询处理流程,基于《MySQL 技术内幕-SQL编程》,该书对SQL编程做了非常详细的介绍,其中第三章讲解了MySQL中如何对查询进行处理。
一个可能的SQL查询语句可能会包含以下内容:
SELECT DISTINCT<select_list> FROM<left_table> <join_type>JOIN<right_table> ON<join_condition> WHERE<where_condition> GROUP BY<group_by_list> WITH{CUBE|ROLLUP} HAVING<having_condition> ORDER BY<order_by_list> LIMIT<limit_number>
基本上,无论多复杂的一个查询语句,都可以通过上述表达式构成。查询操作是关系数据库中使用最为频繁的一类操作,也是构成其他SQL语句的基础。SQL不同于其他典型编程语言(C、C++、Java)的一个很明显的不同就体现在DBMS对SQL的处理流程上。
在上述11个步骤中,首先执行的总是FROM操作,最后执行LIMIT操作。每个操作在DBMS中都会产生一个虚拟表,用于暂存一个步骤的处理结果,同时作为下一个处理步骤的输入。这些产生的虚拟表对用户是透明的,只有最后一步生成的虚拟表才以结果的形式返回给用户。
(1)FROM:对FROM子句中的左表<left_table>和右表<right_table> 执行笛卡尔积操作,如果左表有m行,右表有n行,则进行笛卡尔积产生的虚拟表VT1就有m*n行数据;
(2)ON:对虚拟表VT1应用ON筛选,只有那些符合<join_condition>的行才会被保留到虚拟表VT2中;
(3)JOIN:如果指定了OUTER JOIN ,那么保留表中未匹配的行作为外部行添加到虚拟表VT2,产生虚拟表VT3。如果FROM子句包含两个以上表,则对上一个连接生成的结果表VT3和下一个表重复步骤1-步骤3,直到处理完所有的表为止;
(4)WHERE:对虚拟表VT3使用WHERE过滤器,只有符合<where_condition>被插入到VT4;
(5)GROUP BY:根据GROUP BY中的条件,对VT4中的记录进行分组操作,产生VT5;
(6)CUBE|ROLLUP:对虚拟表VT5进行CUBE或ROLLUP操作,产生VT6;
(7)HAVING:对虚拟表VT6应用HAVING过滤器,对分组之后的记录进行<having_condition>过滤,只有满足分组要求的记录被插入虚拟表VT7;
(8)SELECT:第二次执行SELECT操纵,选择指定的列,插入到虚拟表VT8中;
(9)DISTINCT:去除VT8中的重复数据,产生虚拟表VT9;
(10)ORDER BY:将虚拟表VT9中的记录按照`进行排序操作,产生虚拟表VT10;
(11)LIMIT:取出LIMIT指定的行记录,产生虚拟表VT11,并返回给用户。