一.数据库驱动

一个应用程序如果需要与数据库进行交互,那么就需要数据库驱动。数据库驱动会在底层帮助应用程序建立网络连接,一旦连接建立应用才可以根据编写的代码逻辑发送请求要求数据库进行执行,如下图:

01.MySQL执行逻辑分析 - 图1

对于Java系统而言,如果是通过maven构建应用,需要在pom.xml文件中添加如下驱动的依赖包即可:


mysql
mysql-connector-java
5.1.46

所以对于Java语言开发的应用会提供Java版本的 MySQL驱动。对于Perl,NET,Python,Ruby等各种常见的编程语,MySQL都会提供对应语言的MySQL驱动,让各种语言编写的系统通过 MySQL驱动去访问数据库。

二.数据库连接池

我们开发Java应用一般而言需要部署在Web容器中才可以对外提供服务,例如:Tmocat。
对于Tomcat来说是有多个线程来并发处理来自客户端的请求。如果这些请求都需要访问数据库资源,假设都去抢夺一个网络连接的话,效率是非常低下的,就像下图这样:

01.MySQL执行逻辑分析 - 图2

那么如果Tomcat中的每个线程在每次访问数据库时都基于MySQL驱动去创建一个连接,在执行完毕相关指令之后再销毁这个数据库连接,是否可行呢?如下所示:

01.MySQL执行逻辑分析 - 图3

这种方案似乎不需要多个线程再去争抢一个数据库连接。但是这样在流量高峰时,大量的线程去频繁创建数据库连接可能会“打死”数据库,另外执行完指令之后就立即销毁连接这种效率是非常低下的,因为这些连接并不能被有效的复用。在这样的情况之下,需要对数据库连接资源进行池化
这种池化思想分为两个方面:
(1)客户端池化
这里客户端是指应用程序端,一般需要使用一个数据库连接池里维持多个数据库连接,让多个线程使用里面不同的数据库连接去执行SQL语句。在执行完SQL语句之后,不要立即销毁这个数据库连接,而是把连接放回池子里,待后续线程继续使用。如下图:

01.MySQL执行逻辑分析 - 图4

常见的数据库连接池有DBCP,C3P0,Druid等。
(2)服务端池化
这里的服务端是指MySQL端,实际上对于MySQL内部来说也存在一个连接池,用于维护与系统之间的多个数据库连接。除此之外,系统每次和MySQL建立连接时,需要根据请求传递的账号和密码进行验证,这还包括库表权限的验证等。如下图所示:

01.MySQL执行逻辑分析 - 图5

三.SQL接口

数据库服务器连接池中的某个连接一旦接收到了SQL请求,根据计算网络理论一般会分配一个线程对请求进行处理。也就是说在数据库服务端一定存在一个线程来监听请求以及读取请求数据,比如SQL语句。
当MySQL内部的工作线程从一个网络连接中读取请中的SQL语句之后,会交给什么组件会进行后续的处理呢?这个组件就是SQL接口(SQL Interface),该组件的职责就是:提供一套执行SQL语句的接口,用于执行MySQL工作线程接收到的SQL语句并进行处理。如下图所示:

01.MySQL执行逻辑分析 - 图6

四.查询解析器

SQL接口在接收到SQL请求之后该如何处理呢?对于请求来说,SQL只是一串字符串,对于MySQL来说是无法识别的。此时需要由查询解析器(Parser)对SQL进行工作。通俗来说,查询解析器的职责就是按照既定的SQL语法,对我们编写的SQL语句进行解析,MySQL需要理解请求中的SQL指令具体逻辑是什么,如下图所示:

01.MySQL执行逻辑分析 - 图7

五.查询优化器

当查询解析器理解了SQL的语义之后,接下来会通过查询优化器(Optimizer)来选择一个最优的查询路径。一般而言MySQL对SQL语句的理解会有多个路径,查询优化器可以帮助MySQL寻找到最优的执行路径,如下图所示:

01.MySQL执行逻辑分析 - 图8

六.存储引擎

当查询优化器选择了最优查询路径之后,到底应该如何去执行呢?MySQL当前最优的SQL语句的计划交给底层的存储引擎去真正执行。
存储引擎是MySQL架构设计中非常重要的部分。对于MySQL来说需要对数据进行存储,这些数据可以存在内存中,也可以存在磁盘上,而且如何存储需要存储引擎进行管理。如下图所示:

01.MySQL执行逻辑分析 - 图9

存储引擎的职责是执行SQL语句,并且按照一定的步骤去查询内存缓数据,更新磁盘数据,查询磁盘数据等一系列的操作,如下图所示:

01.MySQL执行逻辑分析 - 图10

在MySQL的架构设计中,SQL接口,SQL解析器,查询优化器等组件都是通用组件。但是对于存储引擎来说是支待各种各样的存储引擎的。比如我们常见的InnoDB,MyISAM, Memory等。我们是可以选择使用哪种存储引擎来负责具体的SQL语句执行的。当然现在 MySQL一般都是使用Inno0B存储引擎,至于存储引擎原理这里先不展开。

七.执行器

存储引擎可以帮助我们去访问内存以及磁盘中的数据,那么是什么组件来调用存储引擎接口呢?
这里还漏了一个重要的组件,即执行器。执行器的职责是:根据优化器选择的执行方案(执行计划),通过调用存储引擎接口按照一定的顺序和步骤去执行SQL语句的逻辑。如下图所示:

01.MySQL执行逻辑分析 - 图11