[MySQL学习笔记]一.MySQL架构总览

757 阅读6分钟

一直只会使用MySQL的CRUD,对其原理并不了解,所以打算深入学习一下MySQL的原理,看看MySQL到底是个啥。

MySQL架构

为了更好的分析梳理MySQL的架构,用一条Select语句的执行作为i线索来一步一步分析。

图解总览

先看官网给出的图:

一下子接触这么多陌生的模块,还是全英文,多少有点害怕,所以为了更好的理解,我根据以一条查询语句的执行过程为线索重构了一下这张:

接下来就是对各个组件的解释

MySQL架构组件

连接器

我们的程序要使用数据库的第一步,就是要与数据库建立连接,而连接器就是干这样一件事的组件。

首先MySQL 必须要运行一个服务来等待连接,默认监听的 3306 端口。MySQL 是支持多种通信协议的,可以使用同步/异步的方式,支持长连接/短连接。

一些常用的查询参数:

  • show global variables like 'wait_timeout'; -- 非交互式超时时间,如 JDBC程序
  • show global variables like 'interactive_timeout'; -- 交互式超时时间,如数据库工具
  • show global status like 'Thread%'; -- 查看当前MySQL有多少个连接

查询缓存

我们知道Redis可以用作独立的缓存服务器,而在早些年Redis还不流行的时候,MySQL内部也有一个自带的缓存模块。

缓存的作用我们应该很清楚了,把数据以K,V的形式放到内存里面,可以加快数据的读取速度,也可以减少服务器处理的时间。

MySQL默认是将这个缓存模块关闭的,也就是不推荐大家使用,主要是因为MySQL 自带的缓存的应用场景有限。第一个是它要求 SQL 语句必须一模一样,中间多一个空格,字母大小写不同都被认为是不同的的 SQL。 第二个是表里面任何一条数据发生变化的时候,这张表所有缓存都会失效,所以对于有大量数据更新的应用,也不适合。所以,在MySQL8.0中缓存模块已经被移除了。

解析器

过了缓存模块,下一步就到了解析器。解析器的作用是帮我们分析MySQL语句语法是否有误。比如你输入一行错误的SQL语句如selcet table into update insert;,就是这个模块会给你报语法错误,同时告诉你从哪里开始出错了。

最终解析器将一条字符串(语句),拆分成一个一个单词,解析成一个解析树。

预处理器

解析器确认语法没错了之后,预处理器就是来确保我们SQL语句的语义也没有错误,注意语法和语义的区别。比如我执行了这么一条SQLselect * from JonyJava;,这句语法上没有错误,解析器判断正确,然鹅并没有JonyJava这张表,这时候预处理器就会提示出错信息了。

优化器

一条 SQL 语句是可以有很多种执行方式的,最终返回相同的结果,他们是等价的。但是如果有这么多种执行方式,这些执行方式怎么得到的?最终选 择哪一种去执行?根据什么判断标准去选择?

MySQL 的查询优化器的模块(Optimizer)就是来解决这些问题的。

查询优化器的目的就是根据解析树生成不同的执行计划(Execution Plan),然后选择一种最优的执行计划,它会自动帮我们选择合适的索引,选择合适表查询顺序。

MySQL 里面使用的是基于开销(cost)的优化器,那种执行计划开销最小,就用哪种。

优化器最终会把解析树变成一个查询执行计划,查询执行计划是一个数据结构。

当然,优化器不是万能的,他得出的查询计划不一定是最优的执行计划,因为MySQL 也有可能覆盖不到所有的执行计划。

执行引擎

执行引擎就是根据不同的要求选择不同的存储引擎,执行优化器所得出来的执行计划。相当于调用存储引擎的公用接口,来适配不同的存储引擎。

存储引擎

存储引擎说白了就是存放数据的,在MySQL 里面,支持多种存储引擎,他们是可以替换的,所以叫做插件式的存储引 擎。

MyISAM

应用范围比较小。表级锁定限制了读/写的性能,因此在Web 和数据仓库配置中,它通常用于只读或以读为主的工作。

特点:

  • 一张表有三个文件,索引和数据分开存放
  • 支持表级别的锁(插入和更新会锁表)。不支持事务。
  • 拥有较高的插入(insert)和查询(select)速度。
  • 存储了表的行数(count 速度更快)。

适合:只读之类的数据分析的项目。

InnoDB

mysql 5.7 中的默认存储引擎。InnoDB是一个事务安全(与ACID兼容)的MySQL存储引擎,它具有提交、回滚和崩溃恢复功能来保护用户数据。InnoDB行级锁(不升级为更粗粒度的锁)和Oracle 风格的一致非锁读提高了多用户并发性和性能。InnoDB 将 用户数据存储在聚集索引中,以减少基于主键的常见查询的 I/O。为了保持数据完整性,InnoDB还支持外键引用完整性约束。

特点:

  • 一张表有2个文件,主键索引和数据存放在一起。
  • 支持事务,支持外键,因此数据的完整性、一致性更高。
  • 支持行级别的锁和表级别的锁。
  • 支持读写并发,写不阻塞读(MVCC)。
  • 特殊的索引存放方式,可以减少 IO,提升查询效率。

Memory

将所有数据存储在RAM中,以便在需要快速查找非关键数据的环境中快速访问。这个引擎以前被称为堆引擎。其使用案例正在减少;InnoDB 及其缓冲池内存区域提供了一 种通用、持久的方法来将大部分或所有数据保存在内存中,而 ndbcluster 为大型分布式 数据集提供了快速的键值查找。

特点: 把数据放在内存里面,读写的速度很快,但是数据库重启或者崩溃,数据会全部消失。只适合做临时表。 将表中的数据存储到内存中

如何选择存储引擎?

  • 如果对数据一致性要求比较高,需要事务支持,可以选择 InnoDB。
  • 如果数据查询多更新少,对查询性能要求比较高,可以选择MyISAM。
  • 如果需要一个用于查询的临时表,可以选择Memory。
  • 如果都不满足,可以根据官网内部手册,用C语言自己写一个存储引擎😁

官网在这:dev.mysql.com/doc/interna…