MySQL 由客户端和服务器端构成,服务器程序直接与要存储的数据打交道,多个客户端程序可以连接到这个服务器程序,向服务器程序发送增删改查的请求,然后服务器程序根据这些请求,对存储的数据进行相对应的处理。
1.2 服务器处理客户端的请求客户端向服务器发送一段文本格式的SQL,那么服务器是如何处理这个请求的呢?如图所示:
从图中可以看出来,服务器程序在处理来自客户端的请求时,大致需要分为 3 部分,连接管理、解析与优化、存储引擎。
1.2.1 连接管理每当有一个客户端进程连接服务器进程时,服务器进程都会创建一个线程池,专门处理与这个客户端的交互;当该客户端退出时会与服务器断开连接,服务器并不会立即把与该客户端交互的线程销毁,而是把它缓存起来,在另一个客户端连接服务器时,把这个缓存起来的线程分配给该新客户端。这样不用频繁的创建销毁线程,节省了开销。
当连接建立后,与该客户端关联的服务器线程会一直等待客户端发送过来的请求。MySQL 接收到的请求是一个文本消息,该文本消息还需要经过各种处理。
1.2.2 解析与优化MySQL 客户端连接到服务器,发送文本请求后,服务器要对改文本进行处理,首先要做查询缓存、语法解析和查询优化等。
- 查询缓存:
MySQL 服务器程序会把刚刚处理过的查询请求和结果缓存起来。如果下一次由同样的请求过来,直接从缓存中查找结果就好了,就不用再去底层的表中查找了。这个查询缓存可以在不同的客户端之间共享,也就是说,A 客户端刚刚发送了一个查询请求,B 客户端之后发送了同样的查询请求,那么客户端 B 的这次查询直接使用查询缓存中的数据了。
- 查询缓存未命中:
- 如果两个查询请求有任何字符上的不同(如空格、注释),都会导致缓存不会命中。
- 如果查询请求中包含某些系统函数、用户自定义变量和函数、系统表,如mysql、information_schema、performance_schema 数据库中的表,则这个请求不会被缓存
- 缓存失效: MySQL 的缓存系统会检测设计的每一张表,只要该表的结构或者数据被修改,比如对该表示用 INSERT、UPDATE、DELETE、TRUNCATE TABLE、ALTER TABLE、DROP TABLE 或者 DROP DATABASE 语句,则于该表有关的所有查询缓存都将变为无效并从查询缓存中删除!
- 查询缓存未命中:
-
语法解析: 如果查询缓存没有命中,就要进入正式查询阶段。因为客户端程序发过来的只是一段文本,所以 MySQL 服务器首先要对这段文本进行分析,判断请求的语法是否正确,然后从文本中将要查询的表、各种查询条件都提取出来放到 MySQL 服务器内部使用的一些数据结构。
-
查询优化: 语法解析后,服务器得到需要的信息,比如要查找那张表等,但我们写的 SQL 语句执行起来效率可能并不是很高,所以 MySQL 的优化程序会对我们的语句做一些优化(如外连接改为内连接等),优化的结果就是生成一个执行计划,它表明了应该使用那些索引执行查询,以及表与表之间的连接顺序是怎样的。
表是有一行一行的记录组成的,但这只是逻辑上的概念,在物理上如何表示记录,怎么从表中读取数据,以及怎么把数据写入具体的物理存储器上,都是存储引擎负责的。存储引擎封装了数据的存储和提取操作。MySQL 提供了各式各样的存储引擎,不同的存储引擎管理的表可能有不同的存储结构,采用的存储算法也可能不同。
为了方便管理,把 MySQL 服务器处理请求的过程简单的划分为 server 层和存储引擎层。连接管理、查询缓存、语法解析、查询优化这些并不涉及真实数据操作的功能化为 server 层的功能。存取真实数据的功能化为存储引擎层。
1.3 常用的存储引擎 最常用的就是 InnoDB、MyISAM、MEMORY。其中 InnoDB 是 MySQL 默认的存储引擎。
1.4 存储引擎的一些常用用法- 查看当前服务器程序支持的存储引擎:
SHOW ENGINES;
- 创建表时指定表的存储引擎:
CREATE TABLE 表名( 建表语句; )ENGINES = 存储引擎名称;
- 修改表的存储引擎
ALTER TABLE 表名 ENGINES = 存储引擎名称;
- 修改表的存储引擎
ALTER TABLE 表名 ENGINES = 存储引擎名称;



