MySQL基础架构
MySQL是 C/S(Client端 / Server端)
架构。
架构图
MySQL架构包含 Server层
和 存储引擎层
。
- Server 层包含
连接器
、分析器
、优化器
、执行器
。 - 存储引擎层包含
引擎层
、存储层
。
一、连接器
连接器的作用
- 跟客户端建立连接。
- 维持和管理连接。
- 校验用户和获取用户权限。
校验用户
客户端进行连接MySQL的命令如下:
mysql -h$ip -P$port -u$user -p
在网络连接 TCP 握手成功之后,连接器会校验用户名和密码。
- 如果用户名或者密码错误,会直接返回错误提示
Access denied for user
。
获取用户权限
用户名密码认证通过后,连接器会到权限表查询用户拥有的权限,并赋予对应操作权限。
假如连接成功后修改用户权限,也不会影响已经建立连接过的用户。只有断开当前连接重新连接,权限才会生效。
数据库连接池
客户端与数据库建立连接的过程是比较复杂的,流程如下:
- TCP建立连接的三次握手。
- MySQL认证的认证校验。
- 真正的SQL执行。
- MySQL的关闭。
- TCP的四次挥手关闭连接。
数据库连接池能够维护一定的数据库长连接,方便客户端复用,当客户端需要连接数据库时,从连接池获取连接,用完归还即可。无需关心数据库连接池是如何管理这些连接的。
在使用连接池后,除了首次需要进行 MySQL连接的初始化,后续使用只需要关注 执行SQL 这部分的开销。
常见的数据库连接池有:
- Druid
- C3p0
池化思想
一般是对象的池化。核心思想是空间换时间
。
使用预先创建好的对象来减少频繁创建对象的损失,重复利用对象,同时还能够对对象统一管理。
比如:线程池
、数据库连接池
、字符串常量池
。
SQL接口
SQL语句的入口,接受用户的SQL命令,支持接受 DMS,DDL语句,还支持视图、存储过程,并将最终结果返回给用户。
二、查询缓存
在连接器建立连接之后,通过SQL接口接入的SQL语句,若执行的是 select
语句,则连接器会先查询缓存。
- 查询缓存命中的话,会 判断用户是否有操作表的权限,符合权限会直接返回结果。
- 查询未命中,会继续后面的执行阶段。
缓存的原理
之前查询的结果会以 K-V 结构存储在缓存中,其中 K 为执行的SQL,V为查询的结果。
当数据表记录更新删除的时候,要同步修改缓存中的数据。
查询缓存的弊端
查询缓存的 K 需要保证 SQL语句保持一致才会利用到缓存,这也导致查询缓存的场景有局限性。
若更新删除频繁,查询缓存的利用率会更低。
因为更新删除数据表后,该表在缓存中的记录要被全部删除。可能存在数据存入缓存还未利用,便被更新操作删除了。
查询缓存适用于不会频繁变动的数据表,比如配置信息表。
手动使用查询缓存
在 select
语句中,使用关键字 SQL_CACHE
可以手动指定查询缓存。
select SQL_CACHE * from class where id =1
MySQL8.0 删除了 查询缓存 这部分功能。
三、分析器
分析器会解析传入的 SQL语句,进行语法分析。
词法分析
MySQL通过语法分析,能够知道 SQL 语句需要执行的功能。
解析 SQL 语句中的关键字
,比如 SELECT 关键字,表名等。
语法分析
语法分析的作用是 校验 SQL 的合法性
。
若 SQL 语句不满足语法规定,会提示 语法错误。
mysql> elect * from t where ID=1;ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'elect * from t where ID=1' at line 1
语法规定包括 表名
、字段名称
的校验,还有参数等的校验。
四、查询优化器
SQL 语句在被执行之前,会被查询优化器进行优化。
优化器在以下情况下会被使用:
操作的表包含多个索引。
优化器会选择合适的索引。
SQL 语句包含连接(JOIN)查询。
javaselect * from A join B using(ID) where A.c = 10 and B.d=20
比如先查询 A 表,c=20的记录,再根据 ID 查询 B 表,d=20的记录。假如反过来先查询 B 表,再根据 ID 查询 A 表。
虽然查询结果一致,但是前后效率是不一致的。
优化器会选择先执行哪部分效率会更高。
五、执行器
分析器使 MySQL 知道了 SQL语句要做什么,通过优化器对SQL 进行了优化。
最终需要执行器进行 SQL 执行。
权限校验
在执行 SQL 语句之前,执行器会对 SQL 语句中涉及到的表进行 权限校验。
- 如果没有操作表的权限,会提示权限不足。
mysql> select * from T where ID=10;ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'
- 如果权限校验通过,会进行 SQL 执行。
执行器的执行流程
select * from Test where ID=10;
执行器会获取 SQL 语句中的数据表 Test
定义的引擎(InnoDB),再根据引擎的定义接口执行语句。
比如没有索引的情况,执行流程如下:
- 调用 InnoDB引擎接口,获取
Test
表的第一行,判断 ID = 10。- 若不是则跳过,若是则将结果存到结果集中。
- 调用引擎接口
取下一行
。重复第一步的逻辑,直到读到表的最后一行。 - 将结果集中所有满足条件的记录返回给客户端。
- 将 SQL语句与搜索结果以 K-V形式存入查询缓存。
思考问题
如果表 T 中没有字段 k,而你执行了这个语句 select * from T where k=1
, 那肯定是会报“不存在这个列”的错误: “Unknown column ‘k’ in ‘where clause’”。你觉得这个错误是在我们上面提到的哪个阶段报出来的呢?
在分析器的语法分析阶段报出来。