MySQL 逻辑架构与常用的存储引擎

文章目录

  • 概述
  • 逻辑架构示意图
  • Server 层功能模块
    • 连接器
    • 查询缓存
    • 分析器
    • 优化器
    • 执行器
  • 存储引擎层
    • InnoDB
      • InnoDB 主要特性
      • InnoDB 引擎下的查询过程
    • MyISAM
      • MyISAM 的主要特性
      • MyISAM 引擎下的查询过程
    • InnoDB 和 MyISAM 的对比

概述

MySQL 是我们平时开发中最常用的关系型数据库,学习 MySQL 的逻辑架构相当于从全局去理解 MySQL 的运行机制,对于 MySQL 的学习和使用都会有较大的帮助。

逻辑架构示意图

下面就是 MySQL 的逻辑架构示意图:
在这里插入图片描述

从宏观角度来看,MySQL 可以分为两部分:

  • Server 层:是客户端与存储引擎的中间层,提供了 MySQL 对外暴露的所有功能
  • 存储引擎层:负责数据的实际存储和读取

Server 层功能模块

MySQLServer 层提供了对外暴露的所有功能,例如请求连接、认证、语法/词法分析、执行语句优化、查询缓存、内置函数、语句执行等功能。这些功能分别由不同的功能模块提供,模块与模块之间的分工非常明确;同时,也是由这些模块的相互协作,最终给我们提供了可用的 MySQL 服务。

连接器

连接器是负责与客户端建立连接权限管理,以及管理连接的功能模块。
连接器的功能职责比较清晰,但也有些细节需要关注:

  • 建立连接时,如果认证成功,连接器会把当前时刻的用户权限快照作为这个连接后续的权限判断逻辑的依据,直到连接断开
    • 这也意味着,当一个用户成功建立了连接后,即使对这个用户的权限进行了修改,也不会影响已经存在的连接权限判断
  • 连接建立成功后,连接的最大空闲时间(即什么操作都不执行的时间)由 wait_timeout 参数控制,默认为 8 小时
    • 如果在空闲时间超时后,再发送操作请求,那么将会收到 MySQL 返回的错误消息:Lost connection to MySQL server during query
    • 如果在空闲时间超时后,想要再次正常地发送请求,那么需要重新建立连接

查询缓存

查询缓存,主要用于将相同的查询语句的结果给缓存起来。查询缓存的工作原理如下所示:

  • 执行查询语句之前,MySQL 会在内存中查看之前是否执行过相同的一模一样的)语句
    • 如果有,那么直接将缓存中的结果集返回,并结束本次的查询语句执行流程
  • 如果没有,那么将正常走后面的逻辑,直到拿到结果集
  • 查询缓存拿到结果集后,将本条查询语句与查询得到的结果集以 K-V 的形式缓存到内存中
  • 将结果集返回,本次查询语句执行流程结束

既然有缓存,那么就需要考虑数据一致性的问题。MySQL 给出的解决方案就是当一个表进行了更新/新增操作后,这个表上的所有查询缓存都会失效。
这样一来,查询缓存的功能就变得非常鸡肋了。具体的原因有:

  • 查询语句完全相同的概率可能并不高
  • 执行缓存操作本身也是需要耗费时间和空间的
  • 最主要的原因是清空缓存的触发条件过于简单,但是影响却十分巨大(只有表上有一个更新/新增操作,那么这个表上的所有查询缓存都会被清空)

综合来说,即在大多数场景下,查询缓存带来的性能提升效果可能比不上执行缓存操作本身带来的性能消耗,即查询缓存不值得使用。
当然,在一些几乎完全不会发生更新/新增操作的表上,这个查询缓存还是可能会起到提升性能的作用的。
MySQL 8.0 之前可以通过将 query_cache_type 改为 DEMAND,并在查询语句的查询返回字段前增加 SQL_CACHE 关键字来显示指定使用查询缓存,例如:

select SQL_CACHE * from user where id = 1;

需要注意的是,MySQL8.0 及之后的版本将查询缓存功能彻底移除了。

分析器

在客户端向服务端发送了一条 SQL 语句之后,MySQL 需要分析这条 SQL 语句是否合法;如果合法,那么这条 SQL 语句究竟是想要执行什么操作。这就是分析器的职责。
分析的过程,主要分为词法分析语法分析

  • 词法分析:将输入的 SQL 语句中的所有单词由空格隔开的字符串)识别为不同的含义
    • 例如,把 selectupdate 给识别出来这是一个操作关键字,把输入的 distinct 识别为一个去重的关键字
  • 语法分析:根据词法分析的结果以及当前配置的 SQL 执行模式(sql_mode 参数),判断这条 SQL 语句是否合法
    • 如果不合法,那么将会直接返回一个语法错误
    • 如果合法,那么 MySQL 就会将 SQL 语句的执行意图给解析出来

优化器

在经过分析器的词法分析语法分析后,SQL 语句的执行流程就来到了优化器。由上面的逻辑我们可以知道,到达优化器的语句必定是一个合法的,且执行意图已知的 SQL 语句。
优化器的作用,就是尝试为 SQL 语句的执行意图,挑选出一种效率最高的执行方案
例如,在一个要执行查询语句的目标数据表中,可能存在多个索引,优化器将会根据这些索引的类型以及字段组合,结合查询语句本身的条件,为其挑选一个最优的索引,以便用于后续真正的数据查询。
又或者,在一个有多表关联的查询语句中,根据表连接的字段以及各表的数据量,决定表与表之间的连接顺序以及使用的算法。
优化器的工作结束后,这条语句的执行方案就确定下来了。值得一提的是,我们使用 explain 关键字用于分析一条 SQL 语句的执行计划时,返回的正是优化器的一部分分析结果。

执行器

MySQL 通过分析器已经知道了 SQL 语句的执行意图,并且通过优化器已经为这条 SQL 语句挑选除了一种效率最高的执行方案,那么 SQL 语句的执行流程将会来到执行器
执行器的主要工作为:

  • 首先查看当前用户是否具有 SQL 语句中的目标表的对应操作权限
    • 如果没有,例如当前用户没有对于目标表的查询权限,那么将会直接返回权限错误
  • 如果有权限,那么将会调用当前使用的存储引擎的对应操作接口,执行这条 SQL 语句真正的执行意图
    • 例如,当前使用的存储引擎是 InnoDB,当前执行的 SQL 语句是 select * from user where id=1,那么执行器将会调用存储引擎层的查询接口执行对于 user 表的具体查询操作

存储引擎层

存储引擎层负责真正的数据存储和提取,其结构(对于 Server 层来说)是插件式的,封装了具体的存储引擎的操作逻辑。
存储引擎的服务对象是表。意思就是说,不同的表可以使用不同的存储引擎;同一个数据库中的不同表也可能使用不同的存储引擎。
下面将介绍常用的两个存储引擎:InnoDBMyISAM

InnoDB

InnoDBMySQL 5.5 版本后的默认存储引擎,也是日常开发过程中使用的最多的存储引擎。
使用 InnoDB 作为引擎来存储的表, 会对应磁盘上的两个文件:

  • *.ibd(索引及数据文件),存储的是聚集索引(索引与数据在同一棵 B+ 树中),以及非聚集索引
  • *.frm(表结构文件)存储的是表结构

InnoDB 主要特性

InnoDB 的主要特性如下所示:

  • 支持事务
  • 支持更细粒度的锁(行锁)
  • 拥有崩溃后安全恢复(crash safe)能力
  • 支持外键

InnoDB 引擎下的查询过程

在使用了 InnoDB 引擎的表的单表查询语句的执行过程将会是这样:

  • 首先看查询条件中是否使用了聚集索引
    • 如果有,直接在聚集索引中进行 B+Tree 查找直到找到数据,并将数据返回,时间复杂度为 O(logN)
  • 如果不是聚集索引,则看查询条件中是否命中的二级索引(非聚集索引)
    • 如果可以命中二级索引,则首先在对应的二级索引树中查找,如果找到了,则取叶子节点上的聚集索引值,再回到聚集索引中(使用刚刚查找到的聚集索引值)进行查询(回表操作),并将数据返回,时间复杂度为 O(logN)
  • 如果二级索引也不能命中,则直接在聚集索引树中遍历所有叶子节点,待全表扫描完后,再将中途查找到的符合条件的所有数据返回,时间复杂度为 O(N)

MyISAM

MyISAMMySQL 最早出现的一批存储引擎之一,但是现在在日常开发过程中已经比较少用。
MyISAM 也有很多优点,但是有一个致命的缺点:不支持事务,没有 crash safe 能力。
使用 MyISAM 作为引擎来存储的表, 会对应磁盘上的三个文件:

  • *.myi(索引文件)存储的是非聚集索引,叶子节点上存储的是数据对应的地址(.myd 文件中的位置)
  • *.myd(数据文件),存储的是实际的数据
  • *.frm(表结构文件),存储的是表结构

MyISAM 的主要特性

MyISAM 的主要特性如下所示:

  • 只支持表锁
  • 内置了一个计数器来存储表的行数
  • 延迟更新索引键:如果在创建表时指定了 DELAY_KEY_WRITE 参数,那么每次更新了(索引相关的)数据后,并不会立刻将修改的索引数据写入磁盘中,而是采用了缓冲区+延时批量写入的设计来延后地、批量地写入更新的索引数据。这样可以极大地提升写入的性能
  • 设计简单,数据以紧密的格式存储:在更新较少的场景下性能表现很好

MyISAM 引擎下的查询过程

在使用了 MyISAM 引擎的表的单表查询语句的执行过程将会是这样:

  • 首先看查询条件中,是否有可以命中的索引
    • 如果有,则在索引文件中进行 B+Tree 查找直到找到数据的地址,然后再通过数据地址在数据文件中找到对应的数据,时间复杂度为 O(logN)
  • 如果没有,则在数据文件中遍历所有数据行,待全表扫描完成后,再将中途查找到的符合条件的所有数据返回,时间复杂度为 O(N)

InnoDB 和 MyISAM 的对比

InnoDBMyISAM 的主要区别有:

  • MyISAM 不支持事务,InnoDB 支持事务:两个存储引擎最大的两个区别之一,MyISAM 不支持事务的特性导致了它在注重数据一致性的场景下无法使用
  • MyISAM 不支持崩溃后的安全恢复(crash safe),而 InnoDB 则支持:也是两个存储引擎最大的两个区别之一,MyISAM 不支持 crash safe 导致了它在注重数据安全的场景下无法使用
  • MyISAM 只支持表锁,而InnoDB 既支持表锁也支持行级锁:MyISAM 只支持表锁的特性,在更新操作稍多的场景下,读写性能会大幅下降,这也导致了在这种场景下 MyISAM 的使用率将会比较低
  • 对表的行数查询的支持不同:
    • MyISAM 内置了一个计数器来存储表的行数,在需要查询表的行数时直接从计数器中拿出即可
    • InnoDB 需要去统计所有的行数,在高版本的 MySQL 中,InnoDB 也会有一个存了行数的变量,但这只是个估计值,需要准确的值时仍需要去实时统计
  • MyISAM 不支持外键,InnoDB 支持外键
  • delete from table 的处理方式不一样:
    • MyISAM直接重新建表
    • InnoDB 会一行一行的删除
  • 文件存储方式不同:
    • MyISAM :一个表在磁盘上对应三个文件:*.myi(索引文件)、*.myd(数据文件)、 *.frm(表结构文件)
    • Innodb:一个表在磁盘上对应两个文件:*.ibd(数据及索引文件)、 *.frm(表结构文件)

总的来说,在不考虑数据一致性以及数据安全性,且查询操作远多于更新操作的场景下,可以考虑选择 MyISAM 作为存储引擎;否则都应该选择 Innodb 引擎

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

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

相关文章

java 阿里云接口实现发送短信验证码

1.先去阿里云开通短信服务: 2.添加模板及签名:需要审核,个人账户审核就几分钟就OK 先解释一下模板及签名: 标准参照:https://help.aliyun.com/document_detail/55324.html?spm5176.sms-sign.0.0.765c1cbeNhvWBZ 去…

MySQL 索引底层数据结构实现

文章目录概述讨论范围查询数据结构查询数据结构种类及其高性能查询原理MySQL 索引的底层数据结构MySQL 索引的需求分析选择 MySQL 索引的底层数据结构B- 树和 B 树的对比MySQL 索引的底层数据结构揭秘概述 MySQL 的索引是存储引擎用于快速找到记录的一种数据结构,是…

Java面试——SpringMVC系列总结

文章目录: 1.什么是Spring MVC? 2.Spring MVC的主要组件有哪些? 3.请描述一下Spring MVC的工作流程? 4.MVC是什么?MVC设计模式的好处有哪些 5.拦截器Interceptor与过滤器Filter有什么区别? 6.Spring …

中蒙俄经济走廊背景_上海外国语大学师生代表团参观访问G60科创走廊俄罗斯院士创新基地...

10月23日,上海外国语大学团委书记、创新创业与实践教育学院执行院长廖文其、俄罗斯东欧中亚学院党总支副书记郝佳、辅导员石朝天及学生代表等一行15人参观访问G60科创走廊俄罗斯院士创新基地(下简称:创新基地)。创新基地主任赵磊、俄罗斯中小企业联合会华…

MySQL 索引类别与索引使用指南

文章目录概述MySQL 索引类型MySQL 索引方法BTREE 方法HASH 方法主键构成的索引结构主键索引的优点主键索引的缺点依赖顺序插入更新代价高索引使用指南索引树回顾索引树排序规则最左前缀法则最左前缀法则的产生依据最左前缀法则延申字段书写顺序不影响最左前缀法则最左前缀法则总…

测试员不可不知的几款bug管理工具

根据每个公司性质的不同,规模的不同,所用到的bug管理工具也可能不同。你们用的bug管理工具是什么呢?下面介绍几款主流的bug管理工具: 1. JIRA(付费) JIRA的生产者把JIRA定义为Professional Issue Tracker&…

Bugzilla 使用指南

本篇文章主要关注于如何高效合理的使用Bugzilla。 Bugzilla是一个开源的缺陷跟踪系统,它可以管理软件开发过程中缺陷的提交、修复、关闭等整个生命周期。 1. 基本概念 在Bugzilla中,Bug报告状态分为以下几种状态, 待确认的 unconfirmed 新…

MySQL explain 命令

概述 MySQL 的 explain 命令,主要用于查看实际查询过程中的一些执行细节(执行计划),也是查看优化器决定如何执行查询的主要方法 explain 使用示例 explain 的使用也很简单,在 select 语句之前增加 explain 关键字再…

centos6.5安装bugzilla超详细教程

经过自己的摸索,与尝试,成功在centos6.5上,安装bugzilla。并且可以发送邮件。 一、安装软件 首先,需要安装一些软件 yum install mysql-devel -y yum install mysql-server -y yum install httpd -y yum install gcc gcc-…

从numpy里加载_PyTorch强化:01.PyTorch 数据加载和处理

PyTorch提供了许多工具来简化和希望数据加载,使代码更具可读性。1.下载安装包scikit-image:用于图像的IO和变换pandas:用于更容易地进行csv解析from __future__ import print_function, divisionimport osimport torchimport pandas as pd #用…

Redmine使用手册

一、Redmine简介 Redmine是基于ROR框架开发的一套跨平台项目管理系统,是项目管理系统的后起之秀,据说是源于Basecamp的ror版而来,支持多种数据库,除了和DotProject的功能大致相当外,还有不少自己独特的功能&#xff0…

swagger2maven依赖_Maven + SpringMVC项目集成Swagger

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。作用&#x…

IDEA2019版最新配置SVN及上传教程-超详细图文详解

IDEA2019版配置SVN图文详解 1. 查看svn仓库 调出svn视图: 连接svn服务器: 连接后效果如下: 补充:如果输入正确的连接地址后出现错误—系统找不到指定的文件 请到设置中检查(File | Settings | Version Control | Subversion)SVC客户端路径…

dubbo:reference、dubbo:service和@Service、@Reference使用情况

以前在同一模块中Spring依赖注入&#xff0c;可以通过Service和Autowired Dubbo是远程服务调用&#xff0c;消费方需要注入提供方定义的接口实例&#xff0c;可以通过xml配置 dubbo:reference、dubbo:service <dubbo:service interface"fei.CustomerServices" …

SSM+Maven+Dubbo+Zookeeper简单项目实战以及易错注意点

最近为了熟悉Dubbo远程过程调用架构的使用&#xff0c;并结合SSMMaven整合了简单的一套项目实战 直接看项目结构图 各模块介绍 dubbo-common&#xff1a;存放项目需要的公众类&#xff0c;像查询模型、数据库实体模型等 dubbo-config&#xff1a;存放项目所需的公众配置文件&…

c++二叉树的层序遍历_leetcode 103. 二叉树的锯齿形层序遍历

按层次遍历&#xff0c;记录下对应节点的val和所在层&#xff0c;然后经过一定变换得到输出。python代码如下&#xff1a;# Definition for a binary tree node.# class TreeNode(object):# def __init__(self, x):# self.val x# self.left None# …

TCP和UDP的区别(Socket)

TCP和UDP区别 TCP和UDP编程区别 TCP编程的服务器端一般步骤是&#xff1a;   1、创建一个socket&#xff0c;用函数socket()&#xff1b;   2、设置socket属性&#xff0c;用函数setsockopt(); * 可选   3、绑定IP地址、端口等信息到socket上&#xff0c;用函数bind(); …

mysql open table_MySQL open table

背景&#xff1a;MySQL经常会遇到Too many open files&#xff0c;MySQL上的open_files_limit和OS层面上设置的open file limit有什么关系&#xff1f;源码中也会看到不同的数据结构&#xff0c;TABLE, TABLE_SHARE&#xff0c;跟表是什么关系&#xff1f;MySQL flush tables又…

JUC详解

JUC 前言&#xff1a; 在Java中&#xff0c;线程部分是一个重点&#xff0c;本篇文章说的JUC也是关于线程的。JUC就是java.util .concurrent工具包的简称。这是一个处理线程的工具包&#xff0c;JDK 1.5开始出现的。下面一起来看看它怎么使用。 一、volatile关键字与内存可见…

抓包工具,知道手机app上面使用的接口是哪个

fiddler。大家可以百度上面好多选择一个安装。这里随便扔一个 在电脑上安装以后。你再配置手机上的一些设置。 首先保证手机和电脑在同一个局域网上&#xff0c;连得wifi域名前面一样的&#xff0c;在电脑的cmd输入ipconfig 然后打开手机的设置。wifi页面点开查看你连的wifi的…