文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star! 搜索关注微信公众号 码出Offer 领取各种学习资料!
MySQL基础架构
一、引言
我们在学习MySQL的时候,迈入MySQL大门的第一步就是了解并安装MySQL客户端,随后才是使用MySQL做一系列数据库操作。但是往往被我们忽略的却是真正了解MySQL基础架构,为什么要这么说呢?因为在对数据库数据CURD操作的时候,也会出现一些问题或异常情况,此时并不是要去盲目的解决问题,而是直戳本质,快速定位并解决问题。
二、MySQL基础架构图
MySQL基础架构可以分为两大类:Server层和存储引擎层
- Server层: Server层涵盖了MySQL大部分核心业务功能,并且所有存储引擎的功能都在这一层实现
- 存储引擎层: 存储引擎有很多,各自有着各自的特点,可以根据场景来选择不同的存储引擎来操作数据
Server层
存储引擎层
Server层
存储引擎层
三、MySQL基础架构零件分析
- 连接器: 管理连接,权限验证
- 分析器: 词法分析,语法分析
- 查询缓存: 命中缓存,返回结果
- 优化器: 执行计划生成,索引选择
- 执行器: 操作引擎,返回结果
- 存储引擎: 存储数据,提供读写接口
四、基础零件剖析
4.1 连接器
使用MySQL数据库,第一步是要连接MySQL数据库,这时候第一个迎接的你就是连接器。连接器负责跟客户端建立连接、获取权限、管理连接等工作。我们一般是使用命令
mysql -uroot -p
+Enter
后输入密码并登录。当输入密码提交登录时,MySQL客户端会与服务器建立连接,在完成TCP握手后,连接器就开始确认你所输入的用户名和密码。如果用户名密码正确则成功登录,如果用户名密码错误,会受到如下错误信息!
登录失败错误信息
image-20200712114731957
登陆成功后,连接器会对你进行权限验证,此时权限验证都依赖于这时候读取到的权限,并根据你的权限而赋予对数据库的操作的权力。正是因为权限验证对验证时权限读取的依赖问题,也反映出了如下注意点!
注意: 一个用户成功建立连接后,即使你用管理员账号对这个用户的权限做了修改,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。
4.2 查询缓存
连接建立完成后,假设你正在使用该SQL语句查询一条数据
select * from tb_user where id = 1
。接下来MySQL执行逻辑就回到了查询缓存中。此时MySQL拿到一个查询请求后,先到查询缓存里看看是否执行过一这条SQL语句,在之前如果执行过这条语句,其结果大概就是以Key-Value(键值对)的形式直接缓存在内存中。这里的Key代指的是查询语句,Value代指的是查询结果。如果你所查询的语句在查询缓存中就命中缓存,它就会把该SQL语句对应的value值结果集返回,这样就并不会执行其他MySQL零部件了,大大提高了查询效率。但是往往利弊是同时存在的,查询缓存有着一个致命的缺点,那就是查询缓存失效十分频繁。这里所说的查询缓存失效是指的只要有对一个表的更新,这个表上所有的查询缓存都会被清空。因此可能你废了很大的劲把结果存起来,还没使用呢,就被一个更新全清空了!大家都知道数据的宝贵,由于这个致命的缺点,导致查询缓存在MySQL8.0版本的时候就被抛弃了,也就是说MySQL8.0版本彻底删除了查询缓存!
4.3 分析器
如果没有命中缓存,那就必须执行SQL语句了。这时候你所写的查询语句就到了分析器,分析器先会对SQL语句进行“词法分析”,它会分析并识别你所输入的空格、字符串和关键字都在MySQL中代表了什么,比如首先它会识别出来select关键字、表名、列名和条件。识别了SQL语句的这些后,就到了“语法分析”的阶段,它会根据MySQL的语句标准来检查你所输入的SQL语句是否符合标准。如果不符合标准就会报出一个“You have an error in your SQL syntax”的语法错误提示。
注意: 一般语法错误提示第一个你所需要关注的是紧接着“use near”的内容,因为它会告诉你哪个语法附近有错误!
4.4 优化器
能进到优化器优化环节的SQL语句,说明在分析器分析的时候没有出现任何错误。那么优化器对该SQL语句做了些什么呢?假如一个SQL语句中是有索引的,优化器会根据优化规则选择合适的索引。或者是一个语句夺标关联时,优化器决定了各个表之间的连接顺序。这里我们看一个多表连接的SQL语句:
select * from tb_user join tb_grade on tb_user.id = tb_grade.uid where tb_user.username = 'Ziph' and tb_grade.subject = 'Java';
先从tb_user表中取出username=Ziph的记录ID,再根据ID关联到tb_grade表,再判断tb_grade表中的subject是否等于Java
先从tb_grade表中取出subject=Java的记录ID,再根据ID关联到tb_user表,再判断tb_user表中的username是否等于Ziph
两种逻辑查询出的结果虽然是一样的,但是执行效率会有所不同,而优化器的作用就是根据自己的优化逻辑判断来决定使用哪一个方案
4.5 执行器
通过分析器知道了做什么,通过优化器知道了怎么做,这就遇到了一个问题,谁来做?可想而知就是执行器开始执行SQL语句。开始执行的时候,要先判断一下你对表是否有执行查询的权限,如果没有就会报出错误的提示信息。如果有权限,就打开表继续执行。执行器会根据表的引擎来调用提供的引擎接口,开始执行。
执行器调用引擎接口执行过程: 调用InnoDB引擎接口取这个表的第一行,判断是否符合查询条件,如果不符合则跳过,如果符合则将这行存在结果集中。以此类推,执行遍历所有行将所有满足条件的记录集作为结果集返回
在这里插入图片描述