Mysql系列(一) - Mysql的架构体系

2023-11-10

目录

前言

MySQL架构图

连接层​编辑

服务层

连接池

缓存

解析器

优化器

执行器

存储引擎层

MyISAM 与 InnoDB 引擎的区别

如何在两种存储引擎中进行选择?

系统文件存储层

数据文件

日志文件(错误日志,binglog和慢查询日志)

redo log文件:

undo log文件:

配置文件

一条SQL执行流程

更新数据SQL的执行流程

总结


前言

从互联网发展至今20几年,mysql这个数据库系统也一直伴随着我们一起发展。mysql是在我们开发过程中常用的数据库利器,也是最让人耳熟能详的,大中小型的业务项目几乎都能胜任,用的多,用的广,大厂面试也常问。

自从2000年mysql开放源代码以来,数据库行业蓬勃发展,特别是nosql的发展更是百家齐放,百家争鸣。这里面多多少少要归因于mysql AB公司的开放胸怀。2000年之后的数据库行业的发展在技术上多多少少都会参考一些mysql的实现思路,以及由mysql的实现思路基础上而激发出新的创新技术来应对不同的数据管理需求的场景。

所以,如果你想成为一名合格或者优秀的架构师,数据库这块的知识可以先从深入学习mysql开始。

今天我们先来聊聊MySQL的架构体系

MySQL架构图

如下是mysql的分层架构图,下面我们对如下的架构图进行拆分,并做简要的说明

连接层

与客户端打交道,上面已经写明了能支持的的语言。客户端的链接支持的协议很多,比如我们在 Java 开发中的 JDBC。

服务层

连接池

主要是负责存储和管理客户端与数据库的链接,一个线程负责管理一个连接。自从引入了连接池以后,官方报道:当数据库的连接数达到128后,使用连接池与没有连接池的性能是提升了n倍(反正就是性能大大的提升了)。

连接建立完成后,就可以执行select语句了。执行逻辑就会先来到缓存模块。

缓存

MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果会以key-value对的形式存储在内存中。key是查询的语句,value是查询的结果。如果你的查询能够直接在这个缓存中找到key(命中),那么这个value就会被直接返回给客户端。

如果在缓存中未命中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。这里可以看到,如果查询命中缓存,MySQL不需要执行后面的复杂操作,就可以直接返回结果,这个效率会很高。

但是大多数情况下我会建议你不要使用查询缓存,为什么呢?因为查询缓存往往弊大于利。

查询缓存的失效非常频繁,只要有对一个表的某一条数据更新,这个表上所有的查询缓存都会被清空

因此可能很费劲地把结果存起来,还没使用呢,就被一个更新全清空了。对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务就是有一张静态表,很长时间才会更新一次。

比如:一个系统配置表,那这张表上的查询才适合使用查询缓存。

好在MySQL也提供了这种“按需使用”的方式。你可以将参数query_cache_type设置成DEMAND,这样对于默认的SQL语句都不使用查询缓存。

「注意」:MySQL 8.0版本直接将查询缓存的整块功能删掉了,标志着MySQL8.0开始彻底没有缓存这个功能了。

解析器

如果没有命中查询缓存,就要开始真正执行语句了。首先,MySQL需要知道你要做什么,因此需要对SQL语句做解析。

分析器先会做“词法分析”。你输入的是由多个字符串和空格组成的一条SQL语句,MySQL需要识别出里面的字符串分别是什么,代表什么。

做完了词法分析以后,就要做“语法分析”。根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法。

如果我们在拼写SQL时候,少了或者写错了某个字母,,就会收到“You have an error in your SQL syntax”的错误提醒。

比如下面这个案例:

错误在于WHERE关键字中差了一个E。

同样,我们使用的SQL如果某个字段不存在。

一般语法错误会提示第一个出现错误的位置,所以你要关注的是紧接“use near”的内容,仅供参考,有时候这个提示也不是非常靠谱。

经过分析器对SQL进行了分析,并且没有报错。那么此时就进入优化器中,对SQL进行优化。

优化器

优化器主要是在我们的数据库表中,如果存在多个多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序 。

比如说:

SELECT a.id, b.id FROM t_user a join t_user_detail b WHERE a.id=b.user_id and a.user_name='田维常' and b.id=10001

它会在条件查询上进行优化处理。

优化器处理完成过后,此时就已经确定了SQL的执行方案。然后继续进入执行器中。

执行器

首先,肯定是要判断权限,就是有没有权限执行这条SQL。工作中可能会对某些客户端进行权限控制。

比如说:生产环境中,对于大部分开发人员都只开查询权限,没有增删改权限(部分小公司除外)。

如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。

存储引擎层

存储引擎的概念是MySQL里面才有的,不是所有的关系型数据库都有存储引擎这个概念 。

数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。现在许多不同的数据库管理系统都支持多种不同的数据引擎。

因为在关系数据库中数据的存储是以表的形式存储的,所以存储引擎也可以称为表类型(Table Type,即存储和操作此表的类型)。

  • MySQL5.5版本(mysql 版本 < 5.5版本) 以前,默认使用的存储引擎是MyISAM 。
  • MySQL5.5版本(mysql 版本 >= 5.5版本) 以后,默认使用的存储引擎是InnoDB 。

下面对部分相对使用多的引擎进行一个对比:

在实际项目中,大多数使用InnoDB,然后是MyISAM,至于其他存储引擎使用的非常至少。

MyISAM 与 InnoDB 引擎的区别

Mysql5.5 版本之前默认的存储引擎就是 MyISAM 存储引擎,MySQL 中比较多的系统表使用 MyISAM 存储引擎,系统临时表也会用到 MyISAM 存储引擎,但是在 Mysql5.5 之后默认的存储引擎就是 InnoDB 存储引擎了。

两个主要原因:

  • 第一个原因是MyISAM 是表级锁定,限制了数据库读/写的性能;
  • 另外一个原因是MyISAM 不支持事务,基于以上两点,InnoDB 引擎可以锁到行。

如何在两种存储引擎中进行选择?

  • 是否有事务操作?有,InnoDB。
  • 是否存储并发修改?有,InnoDB。
  • 是否追求快速查询,且数据修改较少?是,MyISAM。
  • 是否使用全文索引?如果不引用第三方框架,可以选择MyISAM,但是可以选用第三方框架和InnDB效率会更高。

系统文件存储层

系统文件存储层主要是负责将数据库的数据和日志存储在系统的文件中,同时完成与存储引擎的之间的打交道,是文件的物理存储层。

比如:数据文件、日志文件、pid文件、配置文件等。

数据文件

「db.opt文件」:记录这个数据库的默认使用的字符集和校验规则。

「frm文件」:存储于边相关的元数据信息,包含表结构的定义信息等,每一张表都会有一个frm文件与之对应。

「MYD文件」:MyISAM存储引擎专用的文件,存储MyISAM表的数据信息,每一张MyISAM表都有有一个.MYD文件。

「MYI文件」:也是MyISAM存储引擎专用的文件,存放MyISAM表的索引相关信息,每一张MyISAM表都有对应的.MYI文件。

「ibd文件和ibdata文件」:存放InnoDB的数据文件(包括索引)。InnoDB存储引擎有两种表空间方式:独立表空间和共享表空间。

  • 独享表空间使用ibd文件来存放数据,并且每一张InnoDB表存在与之对应的.ibd文件。
  • 共享表空间使用ibdata文件,所有表共同使用一个或者多个.ibdata文件。

「ibdata1文件」:系统表空间数据文件,存储表元数据、Undo日志等。

「ib_logfile0、ib_logfile0文件」:Redo log日志文件。

日志文件(错误日志,binglog和慢查询日志)

错误日志:默认是开启状态,可以通过命令查看:

show variables like '%log_error%';

二进制日志binary log:记录了对MySQL数据库执行的更改操作,并且记录了语句的发生时间、执行耗时;但是不记录查询select、show等不修改数据的SQL。主要用于数据库恢复和数据库主从复制。也是大家常说的binlog日志。

show variables like '%log_log%';//查看是否开启binlog日志记录。show variables like '%binllog%';//查看参数show binary logs;//查看日志文件

慢查询日志:记录查询数据库超时的所有SQL,默认是10秒。

show variables like '%slow_query%';//查看是否开启慢查询日志记录。show variables '%long_query_time%';//查看时长

通用查询日志:记录一般查询语句;

show variables like '%general%';

redo log文件:

redo log顾名思义,就是重做日志,每次数据库的SQL操作导致的数据变化它都会记录一下,具体来说,redo log是物理日志,记录的是数据库页的物理修改操作。如果数据发生了丢失,数据库可以根据redo log进行数据恢复。

InnoDB通过Force Log at Commit机制实现事务的持久性,即当事务COMMIT时,必须先将该事务的所有日志都写入到redo log文件进行持久化之后,COMMIT操作才算完成。

当事务的各种SQL操作执行时,即会在缓冲区中修改数据,也会将对应的redo log写入它所属的缓存。当事务执行COMMIT时,与该事务相关的redo log缓冲必须都全部刷新到磁盘中之后COMMIT才算执行成功。

有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,InnoDB存储引擎会使用redo log恢复到掉宕机前的时刻,以此来保证数据的完整性

InnoDB的redo log 是固定大小,即记录满了以后就从头循环写

undo log文件:

在事务执行的过程中,除了记录redo log,还会记录一定量的undo log。undo log记录了数据在每个操作前的状态,如果事务执行过程中需要回滚,就可以根据undo log进行回滚操作

undo log的存储不同于redo log,它存放在数据库内部的一个特殊的段(segment)中,这个段称为回滚段。回滚段位于共享表空间中。undo段中的以undo page为更小的组织单位。undo page和存储数据库数据和索引的页类似(undlog存的就是事务提交前的真实数据)。因为redo log是物理日志,记录的是数据库页的物理修改操作。所以undo log(也看成数据库数据)的写入也会产生redo log,也就是undo log的产生会伴随着redo log的产生,这是因为undo log也需要持久性的保护。

大家常熟悉的MVCC能力就是通过undolog来实现的。

配置文件

用于存放MySQL所有的配置信息的文件,比如:my.cnf、my.ini等。

「pid文件」

pid文件是mysqld应用程序在Linux或者Unix操作系统下的一个进程文件,和许多其他Linux或者Unix服务端程序一样,该文件放着自己的进程id。

「socket文件」

socket文件也是Linux和Unix操作系统下才有的,用户在Linux和Unix操作系统下客户端连接可以不通过TCP/IP网络而直接使用Unix socket来连接MySQL数据库。

一条SQL执行流程

客户端请求 ---> 连接器(验证用户身份,给予权限) ---> 查询缓存(存在缓存则直接返回,不存在则执行后续操作) ---> 分析器(对SQL进行词法分析和语法分析操作) ---> 优化器(主要对执行的sql优化选择最优的执行方案方法) ---> 执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口) ---> 去引擎层获取数据返回

sql执行流程

更新数据SQL的执行流程

取数据行: 执行器先找引擎取 ID=2 这一行(ID 是主键,引擎直接通过B+树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。)

写入undolog:获取ID=2 这一行的数据写入到对应的undolog

更新数据: 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。

更新内存:引擎将这行新数据更新到内存中,

更新 redo log:同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。

写入binlog:执行器生成这个操作的 binlog,并把 binlog 写入磁盘。

提交事务:执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,触发redolog刷盘,然后事务标记为提交成功。

总结

文章的重点还是让大家对Mysql的整体架构以及sql执行流程有个比较清晰的认识,便于后续学习Mysql其他方面的知识。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mysql系列(一) - Mysql的架构体系 的相关文章

  • 将 Null 与 MySQL 触发器中的另一个值进行比较

    所以这是我的问题 我在更新表行时比较新值和旧值 但新值或旧值有时会为空 所以下面的代码不起作用 我可以解决这个问题吗 谢谢 BEFORE UPDATE ON mytable FOR EACH ROW BEGIN IF OLD assigne
  • MySQL中的字符串分割函数

    谁能告诉我如何在 mysql 中实现 split 函数 其行为类似于 Javascript split 我想要一个这样的功能 SELECT Split a b c d AS splitted 结果如下 splitted a b c d 有谁
  • 将 mysql 查询输出存储到 shell 变量中

    我需要一个变量来保存从数据库检索的结果 到目前为止 这基本上是我正在尝试但没有成功的事情 myvariable mysql database u user p password SELECT A B C FROM table a 正如你所看
  • 连接到 mysql 服务器(localhost)非常慢

    实际上有点复杂 摘要 与数据库的连接非常慢 页面渲染大约需要 10 秒 但页面上的最后一条语句是一个回显 当页面在 Firefox 中加载时我可以看到它的输出 IE 是相同的 在谷歌浏览器中 只有在加载完成后输出才可见 不同浏览器的加载时间
  • LEFT JOIN 返回与 INNER JOIN 相同的结果

    我有一张桌子 磨砂膏 里面有 1600 个独特的物品 第二张桌子有100万以上 我运行 INNER JOIN 并获得 65 个匹配项 SELECT a BW Parent Number a Vendor Name b Parent Supp
  • 为什么 MySQL 将 é 与 e 视为相同?

    我使用 Django Web 应用程序将 Unicode 字符串存储在 MySQL 数据库中 我可以很好地存储 Unicode 数据 但是在查询时 我发现 and e被视为好像它们是同一个角色 In 1 User objects filte
  • MySQL更改表,添加具有唯一随机值的列

    我有一个表 我添加了一个名为phone 该表还有一个 id 设置为自动增量的主键 如何将随机值插入到电话列中 该值不会重复 以下 UPDATE 语句确实插入了随机值 但并非所有值都是唯一的 另外 我没有被卖掉 我投了phone字段也正确 但
  • 提高mysql导入速度[关闭]

    Closed 这个问题是与编程或软件开发无关 help closed questions 目前不接受答案 我有一个很大的数据库22GB 我曾经用过进行备份mysqldumpgzip 格式的命令 当我提取 gz 文件时 它会生成 sql文件的
  • mysql - 有什么方法可以帮助使用另一个索引进行全文搜索?

    假设我有一个 文章 表 其中包含以下列 article text fulltext indexed author id indexed 现在我想搜索特定作者撰写的文章中出现的术语 所以像这样 select from articles whe
  • mysql查询先慢后快

    我有 2 个 myISAM 表 分别称为 tests 和 completed tests 一个有 170 个条目 另一个有 118k 条目 当我运行此查询时 SELECT ct archive ct status ct score ct u
  • 如何在SQL中查找单元格中的重复单词

    我有一个名为 situation 和 entityid 的列 Entityid Situation 1234 In the the world of of 3456 Total universe is is a 任何人都可以给我查询以找到这
  • 在 ADO 查询 (mysql/MyConnector) 中使用参数

    今天我下载并安装了 MyConnector 这样我就可以通过 ADO 使用 Mysql 一切都安装好了 我可以与 ODBC 连接并从我的 delphi 环境进行连接 当我在运行时构建查询时 我收到一条错误消息 项目 Project1 exe
  • 在旧版本的 MySQL (<5.5.0) 中模拟 TO_SECONDS()

    出于性能和简单性的原因 我想以秒的形式获取 MySQL 3 x 服务器中 DATETIME 列的内容 或者实际上任何数字类型 我只是想在使用 UNIX TIMESTAMP 时避免所有明显的时区问题 the我表中的日期确实来自不同的区域设置
  • RESTful Web 服务:java.lang.NullPointerException service.AbstractFacade.findAll

    我使用 NetBeans 7 的 来自数据库的 RESTful Web 服务 向导创建了一个简单的 XML Web 服务 此时 我想从关联的 mySQL 数据库发布用户列表 当我尝试通过其 URL http localhost 8080 d
  • 主机 localhost 不允许连接到此 MySQL 服务器 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我不小心删除了我的用户表 删除了所有用户 现在每当我尝试访问我的数据库时 它都会说 主机本地主机不允许连接到此 MYSQL 服务器 我试过
  • 哈希 MySQL 数据库架构

    我想对 MySQL 数据库模式 没有数据 进行哈希 签名 以便对其进行校验和 以确保它不被其他人修改 我怎样才能实现它 据我了解您的问题 您需要表校验和 checksum table table 所以 我想 只需对空表进行校验和
  • MySQL 中有“connect by”替代方案吗?

    如果我使用 Oracle 有connect by可用于创建分层查询的关键字 目前我正在一个项目中使用MySQL 我想知道是否有替代方案connect by在 MySQL 中 我尝试过谷歌 但到目前为止还没有结果 我想要实现的是通过一个查询从
  • 如何使用 PHP 通过 JSON 发送 HTML 元素?

    以下功能 try query this gt pdo gt prepare SELECT FROM bookings WHERE TourID AND dTourDate and Status NOT LIKE Cancelled quer
  • 将 Python 列表(JSON 或其他)插入 MySQL 数据库

    所以我在Python中有一堆数组数据 嗯 相反 我有一个清单 我试图将此数组存储到 MySQL 数据库中的单个单元格中 我尝试使用 JSON 来序列化我的数据 但也许我不明白 JSON 是如何工作的 因此 在连接到我的数据库后 我尝试了上游
  • MyBatis 枚举的使用

    我知道以前有人问过这个问题 但我无法根据迄今为止找到的信息实施解决方案 所以也许有人可以向我解释一下 我有一个表 状态 它有两列 id 和 name id是PK 我不想使用 POJO Status 而是使用枚举 我创建了这样一个枚举 如下所

随机推荐

  • 思科 计算机网络 第2章测试&考试 答案

    拓展 思科交换机常用命令及配置 测验 当通过 Cisco CLI 配置主机名时 哪三项命名约定将作为指南的一部分 选择三项 A 主机名的长度应少于 64 个字符 B 主机名应全部用小写字符表示 C 主机名应不包含空格 D 主机名应该以一个特
  • 球面如何切分成多个扇面?

    近期在研究使用D3D开发三维显示场景 发现D3D支持的纹理图的大小有限制 这种限制一般由D3D引擎 显卡驱动和显卡硬件共同决定 使用如下代码可以获取当前系统能支持最大纹理大小 D3DCAPS9 caps m pd3dDevice gt Ge
  • Linux 下计算圆周率

    转自 http blog csdn net zhuying linux article details 7298465 oracle sor sys time echo scale 5000 4 a 1 bc l q 输出的是小数点后 位的
  • 防治交换机窃听技术_等保2.0建设基本要求(技术部分)解读(下)

    网御星云对等保2 0基本要求技术部分 以四级为例 对安全计算环境 安全管理中心的控制点逐项解读内容如下 01 安全计算环境 1 1 身份鉴别 a 应对登录的用户进行身份标识和鉴别 身份标识具有唯一性 身份鉴别信息具有复杂度要求并定期更换 b
  • rpgmv存档修改html_使用HTML5存档网站内容更改

    rpgmv存档修改html The majority of web content today exists in a state of retrograde amnesia Created in a moment content is c
  • 从GAN到WGAN及WGAN-GP

    20200910 0 引言 最近看了PassGAN的代码 他是使用了WGAN GP的代码作为GAN的框架 来进行密码生成 由此引出了对GAN的学习 在GAN的研究中 有一个方向就是研究如何使GAN更加稳定的训练 在此之中 WGAN和WGAN
  • 多维时序

    多维时序 Matlab实现LSTM Adaboost和LSTM多变量时间序列预测对比 目录 多维时序 Matlab实现LSTM Adaboost和LSTM多变量时间序列预测对比 预测效果 基本介绍 模型描述 程序设计 参考资料 预测效果 基
  • 【linux线程(壹)】——初识线程(区分线程和进程,线程创建的基本操作)

    作者 努力学习的少年 个人简介 双非大二 一个正在自学c 和linux操作系统 写博客是总结知识 方便复习 目标 进大厂 如果你觉得文章可以的话 麻烦你给我点个赞和关注 感谢你的关注 目录 1 线程和进程 1 1 进程的基本概念 1 2 线
  • JAVA多线程的三种创建方式

    一 概述 在JAVA中 用Thread类代表线程 所有线程对象 都必须是Thread类或者Thread类子类的实例 每个线程的任务就是执行一段顺序执行的代码 JAVA使用线程执行体来容纳这段代码 所以 我们创建线程时 主要是根据实际需求 编
  • FPGA设计:如何用半加器和全加器构成四位全加器

    今天来分享一下关于FPGA设计的文章 如何用半加器和全加器构成四位全加器 首先 我们看一位半加器的代码 1 一位半加器的程序代码及 图 library ieee use ieee std logic 1164 all entity half
  • linux串口编程 gsm,linux 中用n_gsm实现3gpp MUX协议

    n gsm 是一种tty设备上的线路规程 line discipline 来实现3gpp MUX协议 n gsm 实现方法如下 1 kernel配置文件中 打开 CONFIG N GSM y 编译内核 2 cat proc device g
  • KMP算法中next数组的理解

    下面我们对着严老师的代码来一步步分析 next 数组理解 void creat next sstring T int next i 1 next 1 0 j 0 while i
  • MySQL SHOW命令

    文章目录 SHOW命令介绍 SHOW命令用法 常用SHOW命令汇总 常用命令汇总表 服务器运行状态信息 支持的字符集信息 支持的校对规则信息 上一个执行语句的告警信息 上一个执行语句的错误信息 服务器线程信息 用户权限信息 支持的权限列表
  • Android疑难解决-Duplicate class xxx.xxx.xxx found in modules xxx.xxx.xxx

    Duplicate class top zibin luban BuildConfig found in modules jetified Luban 1 1 8 runtime top zibin Luban 1 1 8 and jeti
  • System.Text.Encoding不同字符编码之间进行转换

    System Text Encoding 是 C 中用于处理字符编码和字符串与字节之间转换的类 它提供了各种静态方法和属性 用于在不同字符编码之间进行转换 以及将字符串转换为字节数组或反之 在处理多语言文本 文件 网络通信以及其他字符数据的
  • 每日一道算法题(3)--戳气球问题

    题目 戳气球问题 输入一个包含非负数整数的数组nums代表一排气球 nums i 代表第i个气球的分数 现在 你要戳破所有的气球 请计算出最高的分数 分数的计算规则比较特别 当戳破第i个气球时 可以获得nums left nums righ
  • Python自定义函数的综合应用

    第1关 求最大值函数 编写程序 利用可变长度参数定义一个求任意个数数值的最大值的函数max n a b c 并进行测试 例如 当传入6 9时 输出两个数的最大值 当传入3 9 5 1 12 33 2 10时 输出多个数的最大值 输入任意若干
  • 【经典】环境切换——SpringBoot配置不同环境启用不同的配置文件

    不同环境下切换数据库配置文件 环境切换配置一般在数据库 存储等需要在开发环境和正式环境中进行切换时 避免出错而常用的方式 以下内容以yml文件来举例 我们需要创建两个application文件 application dev yml app
  • SpringCloud利用网关拦截做Token验证(JWT方式)

    关于JWT的内容 请看以下链接 主要看它的原理 以及缺点 https blog csdn net memmsc article details 78122931 步骤1 前端传userName password到后端 后端为springcl
  • Mysql系列(一) - Mysql的架构体系

    目录 前言 MySQL架构图 连接层 编辑 服务层 连接池 缓存 解析器 优化器 执行器 存储引擎层 MyISAM 与 InnoDB 引擎的区别 如何在两种存储引擎中进行选择 系统文件存储层 数据文件 日志文件 错误日志 binglog和慢