良心公众号
关注不迷路
MySQL俨然是时下最流行的关系型数据库之一。
因此,有必要了解MySQL的基础架构,这不仅对日常开发、问题排查会有很大的帮助,而且对设计的想法和优化的思路也是有启发性的。
在本文中,菜鸡将讲述我们日常最司空见惯的增删改查,在MySQL底层,到底是怎样执行的。必须说明的是,由于菜鸡水平有限,仅仅是谈一谈个人理解,如有谬误,请帮忙指出,以免误导看到本文的小伙伴,同时也帮助菜鸡成长。
首先,我们看一下MySQL的基础架构图:
这一张图,涵盖了增删改查操作的主要通用步骤。
从图中我们可以看出,这是典型的CS(Client/Server)结构,客户端与服务器的通信基于TCP协议。从这点来看,其实MySQL和我们常见的很多应用类似,只不过是MySQL是用来处理数据的应用。
从图中可以看出,MySQL分为Server层和存储引擎层两部分。我们整体来看一下这张图中的内容:
Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
存储引擎层负责数据的读写。存储引擎有很多种,常见的有InnoDB、MyISAM、Memory ……。当下最常用的存储引擎是InnoDB,它是MySQL 5.5.5及之后版本的默认存储引擎。
接下来,我们逐一来看这张图中的具体内容:
客户端
客户端,通俗理解,就是我们编写SQL语句的地方,比如navicat。这是我们最熟悉的一块,也是我们日常工作中接触最多的一块,在此,菜鸡就不展开论述。
Server层
Server层包括连接器、查询缓存、分析器、优化器、执行器等。
连接器:
客户端想要操作数据库,首先需要与数据库建立连接,而连接器就是负责与客户端建立、维持、管理连接的。
连接命令如下:
// 如果你在数据库所在机器 mysql -u$user -p // 否则 mysql -h$ip -P$port -u$user -p
另外,连接器还负责权限管理,权限方面有一个需要注意的点就是,权限的修改会在下一次连接时生效。这常常会给新手带来困惑,一句名言就是,重启能解决99%的问题。只需要权限被修改的用户重新建立连接即可生效了。
查询缓存
随着MySQL升级至8.0版本,查询缓存已经是过去时了。查询缓存退出历史舞台自有它的道理。菜鸡认为其主要原因是适用场景比较狭窄。
从功能方面来说,查询缓存会在用户查询数据的时候优先查询缓存,这时候如果缓存命中,则直接返回结果,避免后续的Server层操作以及与存储引擎层的交互,这个查询速度是相当快的,但概率也是相当小的。
为什么这么说呢?因为只需要一个更新操作,就要清空整张表的查询缓存,这也就是其鸡肋之处所在。因此,该功能比较适用于更新频率较低的表。而对于更新操作频繁的表,建议关闭查询缓存,具体可将参数query_cache_type设置成DEMAND。
分析器:
分析器的功能,通俗来说,就是解析你输入的SQL语句,具体包括“词法分析”和“语法分析”。
“词法分析”是指分析你输入的命令字符串,搞清楚字符串的每部分分别代表MySQL里面的什么。举个例子:
select * from table where id = 1;
“词法分析”就是分析,select表示这是一条查询语句,table是表名,id是列名……“语法分析”是指,在经过“词法分析”之后的字符串命令是否符合MySQL的语法要求。
这比较容易理解,在此就不再展开。如果解析正确,则继续走接下来的流程,否则抛各种对应的异常。
优化器:
顾名思义,优化器是在执行之前对SQL语句做优化的,具体可以表现为,决定使用哪个索引,多表join顺序。
总而言之,优化器内部事先定义了一系列规则,符合规则的执行被认为是执行效率更高的。
这里有一个问题,经过优化器优化并不一定就是最优的,这其实很显然,因为预测不可能100%准确,这取决于很多因素,比如存储引擎提供的统计信息,并发查询的影响等等。
执行器:
执行器主要做两件事,一件是判断你有没有当前操作的权限,如果没有,直接返回无权限,如果有,则执行第二件事,调用存储引擎提供的接口,根据SQL命令进行数据的读写操作。
存储引擎层
存储引擎层主要是向Server层提供数据读写的接口。由于本篇文章主要是讲增删改查语句的执行过程,因此,关于存储引擎的其他细节,比如事务的支持,以及索引等相关内容,在此就不再展开,这些内容将会在后续的文章中陆续更新。
至此,我们已经大致梳理了MySQL的基础架构。心里已经对一条SQL语句走过的路有了一定的理解。
最后,我们来用一个具体的例子,来实际走一遍这个流程。
我们以下面查询操作为例,事实上,增删改查操作走过的大致路径是一样的,只是在一些细节上的处理略有不同:
select * from table where id = 1;
连接器:客户端与数据库建立连接
查询缓存(建议关闭):查询是否有缓存
分析器:通过“词法分析”和“语法分析”得到这是一条查询语句
优化器:使用id索引然后
执行器:验证查询权限,调用存储引擎接口,找到这一行,然后返回
至此,我们已经走过了一条MySQL语句所走过的路。以上例子是对于查询语句,对于更新语句,为了保证数据的可恢复,还引入了redo log和binlog等相应的日志文件处理,这将在后续文章中讲述。
学习 | 工作 | 分享
????长按关注“有理想的菜鸡”
只有你想不到,没有你学不到