MySql的基本架构示意图如下
mysql总体上可以分为server层和存储引擎层
- server层:包括连接器、查询器、分析器、优化器、执行器等,涵盖mysql的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等
- 存储引擎层:负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memery等多个存储引擎。现象最常用的存储引擎是InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。
Server层组成部分
连接器
- 连接器主要负责客户端和数据库服务的连接工作。
- 可以通过
show processlist
查询当前可用的连接进行的状态。 - 客户端连接后,如果长时间没有通讯连接,就会自动断开链接,默认wait_timeout参数的值是8小时
链接器是如何管理客户端连接的
主要有两个功能
(1)管理连接(相当于一个线程池)
- 客户端可以采用TCP/IP、域套接字等方法连接到服务器
- 每当有一个客户端进程连接到服务器时,服务器进程都会创建一个线程专门来处理与这个客户端的交互
- 当该客户端退出时会与服务器断开连接,服务器并不会立刻把与该客户端交互的线程销毁,而是把它缓存起来
- 当另一个新的客户端再进行连接时,把这个缓存的线程分配给该新的客户端。
- 小结:
- 链接器本质上是一个线程池,MySQL会为每一个连接分配一个线程
- 但是线程分配得太多会严重影响系统性能,所以我们需要限制可以同时连接到服务器的客户端数量
(2)权限认证
- 在客户端程序发起连接时,需要携带主机信息、用户名、密码等信息,服务器程序会对客户端提供的这些信息进行认证。如果认证失败,服务器程序会拒绝连接
- 另外,如果客户端和服务器不再同一台主机上,会通过TLS协议对连接进行加密,从而保证数据传输的安全性
总之:
- 当连接建立后,与该客户端管理的服务器线程会一直等待客户端发送过来的请求。
- MySQL服务器接收到的请求只是一个文本信息,该文本还需要经过各种处理。详情见下面
分析器
- 分析器主要通过词法分析你的SQL语句,用来告诉MySQL你要干什么。
- 这个时候,如果你的sql语句有语法错误,就会报异常:“You have an error in your SQL syntax”
- 如果语法正确,那么就会从文本中将要查询的表、各种查询条件都提取出来放到MySQL服务器内部使用的一些数据结构上。
优化器
- 优化器主要是通过你的sql语句,选择一种最优的方式,告诉MySQL该如何执行该语句。
- 优化的结构就是生产一个执行计划,这执行计划表明应该使用哪些索引进行执行查询,以及表之间的连接顺序等等。我们可以使用EXPLAIN语句来查看某个语句的执行计划
比如如下sql语句:
select * from t1 join t2 using(ID) where t1.a=10 and t2.b=20
那么优化器就会考虑是先通过t1.a=10查询t1的结果值,还是先通过t2.b查询t2的结果。优化器会自动判断出效率最高的一种执行方式,通知MySQL去执行。
执行器
- 执行器通过操作引擎,将SQL语句执行的结果,返回给客户端
- 也就是说,它并不真正的去访问磁盘,而是调用存储引擎提供的各种API,然后获取执行结果
查询缓存
- 查询缓存顾名思义是用来缓存查询结果的。
- 为什么放在最后来说,是因为MySQL8.0版本已经没有了这个功能。这个功能弊大于利,当查询结果命中查询缓存时,会直接返回结果。但大多数时候,我们的使用场景更新的频率会非常频繁,当某一个表中有一条更新数据时,会将该表的查询缓存结果全部清空,效率会非常低。
- 可以使用在一些系统配置表,等更新不频繁的表中。当然我们可手动选择是否开启,参数是:query_cache_type.
存储引擎层
- 我们知道,表是由一行一行的记录组成的,但是这只是一个逻辑上的概念。在物理上如何表示记录,怎么从表中读取数据,以及怎么写入数据,都是由存储引擎负责的事情
- MySQL提供了各种各样的存储引擎,不同存储引擎管理的表有不同的存储结构,不同的存储算法。
- 这些存储引擎为server层提供了同一的调用接口
- 执行器跟根据生成的执行计划调用存储引擎提供的接口,接口会返回处理后的数据给执行器
- 执行器和存储引擎层交互时,一般是以记录为单位的
- 举个例子,比如select语句,server层根据执行计划先向存储引擎层取一条记录,然后判断是否符合where条件
- 如果不符合,那么丢弃该记录,然后继续向存储引擎层要下一条记录
- 如果符合,那么将其发送到一个缓冲区,等缓冲区满了,就将这个缓冲区中的所有记录发送给客户端。缓冲区大小由系统变量net_buffer_length控制
- 存储引擎非常多,但是我们常用的也就是InnoDB、MyISAM(也很少用)、MEMOEY(几乎不用了)
查看当前服务器支持的存储引擎
(root@localhost) [(none)]> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
- Engine:引擎名
- Support:该存储引擎是否可用
- Comment:对当前引擎的一个描述
- Transactions:是否支持事务处理
- XA:是否支持分布式事务
- Savepoints:是否支持事务的部分回滚
如何设置表的存储引擎
存储引擎是负责对表中的数据进行读取和写入工作的,我们可以为不同的表设置不同的存储引擎。
(1)创建表时可以指定存储引擎
- 语法:
-
如果不指定,默认是InnoDB
-
例子:
(2)修改表的存储引擎
- 语法:
- 示例
(3)查看表的存储引擎