深入MySQL的第一步:理解MySQL的架构设计
探究技术的本质,追寻技术的乐趣,今天是我们深入Mysql的第一篇文章,我们通过Mysql是如何执行一条SQL语句,来理清楚MySQL的结构。那么接下来,我们开始吧!
上面的那张图片,展示了MySQL的全景图,总体而言,MySQL采用了C/S架构设计,客户端只负责发送指令和展示结果,大部分的功能都集中在Server端,而Server端也采用了我们都熟悉的分层架构,Server端具体被分为了两层,一个是Service层,主要负责管理客户端的连接,解析SQL,以及优化SQL,最后生成执行计划也就是完成一条SQL语句需要做哪些操作。然后这些操作的具体如何执行是由Storage层来完成的,而Storage层的设计很有意思,采用了插件式的设计,提供统一的抽象的数据存取的接口定义。由不同的存储引擎来实现这些读写接口,最终完成数据的读写。Storage层的设计有没有面向接口编程的味道呢?
相信通过上图,你也大致了解了MySQL的基本构成,接下来我们通过一个例子将这些基本组件串联起来。
我们假设在数据库中已经有了这样的表结构设计。
表的名字叫user,表的字段由userId,username,password,其中userId是主键。现在有一个业务,获取指定userId的用户信息,那么我们就会写出下面这样的SQL语句
select userId,username,password from user where userId=1001
我们就通过这条SQL语句,来看看MySQL是怎么运行的吧,要执行这条SQL语句,我们第一步就是要建立Client端与Server端的联系,也就是建立一个网络连接。对应的命令像这样 mysql -u root -p
, 这样的客户端连接,会被连接器管理,连接器的工作就是维持这个连接,以及校验用户名和密码是否正确,以及读取这个用户的权限。当这些验证通过,连接器会看看缓存中是否存在这条SQL语句对应的结果集,值得注意的是,缓存功能在MySQL8.0就被完全移除了,后面会解释为什么。如果缓存没有命中,SQL语句就会被交给分析器,分析器的作用和编译器的作用差不多,进行词法分析和语义分析,简单来说就是理解这条SQL要干什么?,而优化器会根据这条SQL要完成的事情并结合表的结构,索引等等信息,做出具体的执行计划,也就是完成这条SQL要做的事情,需要哪些步骤。优化器将这些步骤罗列出来,形成一个计划清单,这就是执行计划。执行器拿到这个执行计划,按部就班的执行,在执行的过程中会调用Storage层提供的服务,也就是读写数据到磁盘的接口。不过在执行之前,会先判断用户有没有执行这些步骤的权限,如果没有就会被驳回。如果有,就会执行。具体的执行过程是这样的,由于这是一条查询语句,所以需要将数据从磁盘中加载到内存中,假设userId不是主键,那么执行引擎就是一行一行的比对数据,判断userId是否等于1001,直到遍历完整个数据集。这里之所以会假设userId不是主键,其实是和索引有关,这里先按下不表,后续会详细介绍。当获取到数据集之后,会在缓存中存一份数据,并把数据返回给客户端。这就是一次MySQL一次通信的过程。通过这次过程,我们将各个组件串联起来,知道了他们具体的责任是什么。这一期我介绍了查询语句如何执行的,下一期我们来聊聊更新语句如何执行的,并通过更新语句的执行,引出MySQL中非常重要的日志系统。那么我们下期见。