为了执行SQL语句,MySQL的架构是怎样设计的

1. 把MySQL当个黑盒子一样执行SQL语句

上一讲我们已经说到,我们的系统采用数据库连接池的方式去并发访问数据库,然后数据库自己其实也会维护一个连 接池,其中管理了各种系统跟这台数据库服务器建立的所有连接

我们先看下图回顾一下

当我们的系统只要能从数据库连接池获取到一个数据库连接之后,我们就可以执行增删改查的SQL 语句了

从上图其实我们就可以看到,我们可以通过数据库连接把要执行的SQL语句发送给MVSQL数据库

然后呢?大部分同学了解到这个程度就停下来了,然后大家觉得要关注的可能主要就是数据库里的表结构,建了哪些索引,然后就按照SQL语法去编写增删改查SQL语句,把MVSQL当个黑盒子去执行SQL语句就可以了。

我们只知道执行了inset语句之后,在表里会多出来一条数据;执行了update语句之后,会对表里的数据进行更改;执 行了delete语句之后,会把表里的一条数据删除掉;执行了select语句之后,会从表里查询一些数据出来

如果语句性能有点差?没关系,在表里建几个索引就可以了!可能这就是目前行业内很多工程师对数据库的一个认知,完全当他是个黑盒子,来建表以及执行SQL语句。

但是大家既然跟着我开始学习了,从现在开始就要打破这种把数据库当黑盒子的认知程度,要深入底层,去探索数据 库的工作原理以及生产问题的优化手段!

2. 一个不变的原则:

现在假设我们的数据库服务器的连接池中的某个连接接收到了网络请求,假设就是一条SQL 语句,那么大家先思考一 个问题,谁负责从这个连接中去监听网络请求?谁负责从网络连接里把请求数据读取出来?

我想很多人恐怕都没思考过这个问题,但是如果大家对计算机基础知识有一个简单了解的话,应该或多或少知道-点,那就是网络连接必须得分配给一个线程去进行处理,由一个线程来监听请求以及读取请求数据,比如从网络连接 中读取和解析出来一条我们的系统发送过去的SQL语句,如下图所示:

3. 接口负责处理接收到的SQL语句

接着我们来思考一下,当MySQL内部的工作线程从一个网络连接中读取出来一个SQL语句之后,此时会如何来执行这个SQL语句呢?

其实SQL是一项伟大的发明,他发明了简单易用的数据读写的语法和模型,哪怕是个产品经理,或者是运营专员,甚 至是销售专员,即使他不会技术,他也能轻松学会使用SQL语句。

但如果你要去执行这个SQL语句,去完成底层数据的增删改查,那这就是一项极度复杂的任务了!

所以MySQL内部首先提供了一个组件,就是SQL接口(SQL Interface),他是一套执行SQL语句的接口,专门用于执行我们发送给MySQL的那些增删改查的SQL语句

因此MySQL的工作线程接收到SQL语句之后,就会转交给SQL接口去执行,

如下图

4. 查询解析器:让MySQL语句进行解析

接着下一个问题来了,SQL 接口怎么执行SQL语句呢?你直接把SQL语句交给MySQL,他能看懂和理解这些SQL语句吗?

比如我们来举一个例子,现在我们有这么一个SQL语句:

select id,name,age from users where id=1

这个SQL语句,我们用人脑是直接就可以处理一下,只要懂SQL语法的人,立马大家就知道他是什么意思,但是MVSQL自己本身也是一个系统,是一个数据库管理系统,他没法直接理解这些SQL语句!

所以此时有一个关键的组件要出场了,那就是查询解析器

这个查询解析器 (Parser) 就是负责对SQL语句进行解析的,比如对上面那个SQL语句进行一下拆解,拆解成以下几个部分:

1.我们现在要从“users”表裏查询数据

2.查询”id”字段的值等于1的那行数据

3.对查出来的那行数据要提取里面的“id,name,age”叁个字段

所谓的SQL解析,就是按照既定的SQL语法,对我们按照SQL语法规则编写的SQL语句进行解析,然后理解这个SQL语句要干什么事情,如下图所示:

5. 查询优化器:选择最优的查询路径

当我们通过解析器理解了SQL语句要干什么之后,接着会找査询优化器(0ptimizer)来选择一个最优的查询路径。

可能有同学这里就不太理解什么是最优的查询路径了,这个看起来确实很抽象,当然,这个查询优化器的工作原理,后续将会是我们分析的重点,大家现在不用去纠结他的原理。

但是我们可以用一个极为通俗简單的例子,让大家理解一下所謂的最优查询路径是什么。

就用我们刚才講的那个例子好了,我们现在理解了一个SQL想要干这么一个事儿:我們现在要從users ”表里查询数 据,查询id”字段的值等于1的那行数据,對查出来的那行数據要提取里面的”id,name,age”三个字段。

事是明白了,但是到底应该怎么来实现呢?

你看,要完成這个事儿我们有以下幾個查询路径(纯属用于大家理解的例子,不代表真实的MVSQL原理,但是通过这个例子,大家肯定能理解所谓最优查詢路径的意思):

1.直接定位到'users”表中的id”字段等于1的一行数据,然后查出来那行数据的id,name,age”三个字段的值就可以了

2.先把'users”表中的每一行数据的id,name,age”叁个字段的值都查出来,然后从这批数据裏过滤出来id字段等于1的那行数据的id,name,age”三个字段

上面这就是一个最简单的SQL语句的两種实现路径,其实我们会发现,要完成这个SQL语句的目标,兩个路径都可以做到,但是哪一种更好呢?显然感觉上是第一种查询路径更好一些。

所以查询优化器大概就是干这个的,他会針对你编写的幾十行、幾百行甚至上千行的复雜SQL语句生成查询路径树,

然后从里面选择一条最优的查询路径出来

相当于他会告诉你,你应该按照一个什么样的步骡和顺序,去执行哪些操作,然后一步一步的把SQL语句就合完

我们来一起看看下面的图:

6. 调用存储引擎接口,真正执行SQL语句

最后一步,就是把查询优化器选择的最优查询路径,也就是你到底应该按照一个什么样的顺序和步去执行这个SOL语句的计划,把这个计划交给底层的存儲引警去真正的执行。这个存储引擎是MVSOL的架构设計中很有特色的一个环节。

不知道大家是否思考过,真正在执行SQL语句的时候,要不然是更新数据,要不然是查询数据,那么数据你觉得存放在哪里?

说白了,数据库也不是什么神秘莫测的东西,你可以把他理解为本身就是一个类似你平时写的图书馆管理系统电信计费系统、电商订单系统之类的系统罢了,

数据库自己就是一个编程语言写出来的系统而已,然后启动之后也是一个进程,执行他里面的各种代码,也就是我们 上面所说的那些东西。所以对数据库而言,我们的数据要不然是放在内存里,要不然是放在磁盘文件里,没什么特殊的地方!

所以我们来思考一下,假设我们的数据有的存放在内存里,有的存放在磁盘文件里,如下图所示,

那么现在问题来了,我们已经知道一个SQL语句要如何执行了,但是我们现在怎么知道哪些数据在内存里?哪些数据 在磁盘里?我们执行的时候是更新内存的数据?还是更新磁盘的数据?我们如果更新磁盘的数据,是先查询哪个磁盘 文件,再更新哪个磁盘文件?

是不是感觉一头雾水

所以这个时候就需要存储引擎了,存储引擎其实就是执行SQL语句的,他会按照一定的步骤去查询内存缓存数据,更 新磁盘数据,查询磁盘数据、等等,执行诸如此类的一系列的操作,如下图所示。

MySQL的架构设计中,SQL接口、SQL解析器、查询优化器其实都是通用的,他就是一套组件而已

但是存储引擎的话,他是支持各种各样的存储引擎的,比如我们常见的InnoDB、MYISAM、Memory等等,我们是可以 选择使用哪种存储引擎来负责具体的SQL语句执行的。

当然现在MVSOL一般都是使用InnoDB存储引擎的,至干存储引警的原理,后续我们也会深入一步一步分析,大家不必 着急。

7. 执行器:根据执行计划调用存储引擎的接口

那么看完存储引擎之后,我们回过头来思考一个问题,存储引引擎可以帮助我们去访问内存以及磁盘上的数据那么是谁来调用存储引擎的接口呢?

其实我们现在还漏了一个执行器的概念,这个执行器会根据优化器选择的执行方案,去调用存储引擎的接口按照一定的顺序和步骤,就把SQL语句的逻辑给执行了。

举个例子,比如执行器可能会先调用存储引擎的一个接口,去获取users”表中的第一行数据,然后判断一下这个数据 的“id”字段的值是否等于我们期望的一个值,如果不是的话,那就继续调用存储引擎的接口,去获取“users”表的下一行数据。

就是基于上述的思路,执行器就会去根据我们的优化器生成的一套执行计划,然后不停的调用存储引擎的各种接口去完成SQL语句的执行计划,大致就是不停的更新或者提取一些数据出来

我们看下图的示意

8. 小思考题:打开脑洞,你觉得不同的存储引擎是用来干什么的?

今天给大家留一个小的思考题,就是你先别管MySQL有哪些存储引擎,你就从业务场景来出发考虑,有的场景可能是 高并发的更新,有的场景可能是大规模数据查询,有的场景可能是允许丢失数据的

那么你觉得如果让你来设计存储引擎,你觉得应该有哪些存储引擎,分别适用于什么场景?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/621035.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

苹果备忘录误删一段内容怎么恢复?iPhone备忘录恢复的4种方法!收藏!

在使用苹果设备时,备忘录是许多用户常用的工具之一。iPhone备忘录是一款功能强大、易于使用的应用,它能帮助你更好地管理生活和工作。无论你是记录待办事项、设置提醒还是与他人分享信息,备忘录都能满足你的需求。 然而,如果不小…

Mac下载的软件显示文件已损坏,如何解决文件已损坏问题

当在Mac上下载的软件显示文件已损坏时,这可能是因为多种原因导致的,包括网络问题、下载中断、软件未完整下载、文件传输错误等。解决这个问题需要采取一些步骤来排除可能的原因,并尝试修复文件。下面将详细介绍一些常见的解决方法&#xff1a…

单链表链表专题

1 链表的概念 概念:链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 链表的结构跟⽕⻋⻋厢相似,淡季时⻋次的⻋厢会相应减少,旺季时⻋次的⻋厢会额外增加⼏节。只 需要…

Laravel 11入门:使用ServBay打造高效开发环境

Laravel 11发布,改进了不少功能。 它引入了更加流畅的应用结构、每秒限速、健康路由等特性。 此外,Laravel还推出了第一方可扩展的WebSocket服务器Laravel Reverb,为你的应用提供强大的实时功能。 在今天的指南中,我将设置一个…

【C语言__动态内存管理__复习篇6】

目录 前言 一、动态内存管理 二、动态内存函数 2.1 malloc 2.2 free 2.3 calloc 2.4 realloc 三、动态内存常见的6个使用错误 3.1 接收malloc/calloc返回的参数后未及时检查是否为NULL 3.2 越界访问动态内存空间 3.3 对非动态开辟的内存使用free释放 3.4 使用free只释放了…

「 典型安全漏洞系列 」14.NoSQL注入漏洞详解

NoSQL注入是一个漏洞,攻击者能够干扰应用程序对NoSQL数据库进行的查询,本文我们将研究如何测试一般的NoSQL漏洞,然后重点研究如何利用MongoDB中的漏洞(MongoDB是最流行的NoSQL数据库)。 1. 什么是NoSQL注入 NoSQL注入…

[lesson33]C++中的字符串类

C中的字符串类 历史遗留问题 C语言不支持真正意义上的字符串C语言用字符数组和一组函数实现字符串操作C语言不支持自定义类型,因此无法获得字符串类型 解决方案 从C到C的进化过程引入自定义类型在C中可以通过类完成字符串类型的定义 标准库中的字符串类 C语言直…

古月·ROS2入门21讲——学习笔记(一)核心概念部分1-14讲

讲解视频地址:1.ROS和ROS2是什么_哔哩哔哩_bilibili 笔记分为上篇核心概念部分和下篇常用工具部分 下篇:古月ROS2入门21讲——学习笔记(二)常用工具部分15-21讲-CSDN博客 目录 第一讲:ROS/ROS2是什么 1. ROS的诞生…

Java实现单点登录(SSO)详解:从理论到实践

✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 ✨✨ 帅哥美女们,我们共同加油!一起进步&am…

[docker] 核心知识 - 容器/镜像的管理和操作

[docker] 核心知识 - 容器/镜像的管理和操作 想要查看完整的指令,可以通过 docker --help 列举所有的指令,这里会提到一些比较常用的核心指令 查看容器的状态 这个应该是最常用的指令,语法为 docker ps, ps 为 process status …

【详解算法流程+程序】DBSCAN基于密度的聚类算法+源码-用K-means和DBSCAN算法对银行数据进行聚类并完成用户画像数据分析课设源码资料包

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法。 与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇, 并可在噪声的空间数据…

使用DockerCompose配置基于哨兵模式的redis主从架构集群

文章目录 一、注意事项(坑点!!!)二、配置Redis主从架构集群第一步:创建目录文件结构第二步:编写DockerCompose配置文件第三步:编写redis.conf第四步:启动redis主从集群 三…