MySQL 的运行机制

  • 1) MySQL 是如何运行的
  • 2) 查询缓存的利弊
  • 3)如何选择数据库引擎
  • 4)InnoDB 自增主键
  • 5)小结

1) MySQL 是如何运行的

MySQL 的执行流程是这样的,首先客户端先要发送用户信息去服务器端进行授权认证。如果使用的是命令行工具,通常需要输入如下信息:

mysql -h 主机名(IP) -u 用户名 -P 端口 -p

其中:

  • -h 表示要连接的数据库服务器的主机名或者 IP 信息;
  • -u 表示数据库的用户名称;
  • -P 表示数据库服务器的端口号,
  • 小写的 -p 表示需要输入数据库的密码。

具体使用示例,如下图所示:

当输入正确密码之后可以连接到数据库了,如果密码输入错误,则会提示“Access denied for user ‘xxx’@‘xxx’ (using password: YES)”密码错误信息,如下图所示:

当连接服务器端成功之后就可以正常的执行 SQL 命令了,MySQL 服务器拿到 SQL 命令之后,会使用 MySQL 的分析器解析 SQL 指令,同时会根据语法分析器验证 SQL 指令,查询 SQL 指令是否满足 MySQL 的语法规则。如果不支持此语法,则会提示“SQL syntax”语法错误信息。

当分析器验证并解析 SQL 命令之后,会进入优化器阶段,执行生成计划,并设置相应的索引;当上面的这些步骤都执行完之后,就进入了执行器阶段,并开始正式执行 SQL 命令。同样在执行命令之前,它会先对你的执行命令进行权限查询,看看是否有操作某个表的权限,如果有相应的权限,执行器就去调用 MySQL 数据库引擎提供的接口,执行相应的命令;如果是非查询操作会记录对应的操作日志,再命令执行完成之后返回结果给客户端,这就是整个 MySQL 操作的完整流程。
需要注意的是,如果执行的是 select 语句并且是 MySQL 8.0 之前的版本的话,则会去 MySQL 的查询缓存中查看之前是否有执行过这条 SQL;如果缓存中可以查到,则会直接返回查询结果,这样查询性能就会提升很高。整个 SQL 的执行流程,如下图所示:

我们可以使用 SHOW ENGINES 命令来查看 MySQL 数据库使用的存储引擎,如下图所示:

常用的数据库引擎有 InnoDB、MyISAM、MEMORY 等,其中 InnoDB 支持事务功能,而 MyISAM 不支持事务,但 MyISAM 拥有较高的插入和查询的速度。而 MEMORY 是内存型的数据库引擎,它会将表中的数据存储到内存中,因为它是内存级的数据引擎,因此具备最快速的查询效率,但它的缺点是,重启数据库之后,所有数据都会丢失,因为这些数据是存放在内存中的。

2) 查询缓存的利弊

MySQL 8.0 之前可以正常的使用查询缓存的功能,可通过“SHOW GLOBAL VARIABLES LIKE ‘query_cache_type’”命令查询数据库是否开启了查询缓存的功能,它的结果值有以下三项:

  • OFF,关闭了查询缓存功能;
  • ON,开启了查询缓存功能;
  • DEMAND,在 sql 语句中指定 sql_cache 关键字才会有查询缓存,也就是说必须使用 sql_cache 才可以把该select 语句的查询结果缓存起来,比如“select sql_cache name from token where tid=1010”语句。

开启和关闭查询缓存可以通过修改 MySQL 的配置文件 my.cnf 进行修改,它的配置项如下:

query_cache_type = ON

注意:配置被更改之后需要重启 MySQL 服务才能生效。
查询缓存的功能要根据实际的情况进行使用,建议设置为按需缓存(DEMAND)模式,因为查询缓存的功能并不是那么好用。比如我们设置了 query_cache_type = ON,当我们好不容易缓存了很多查询语句之后,任何一条对此表的更新操作都会把和这个表关联的所有查询缓存全部清空,那么在更新频率相对较高的业务中,查询缓存功能完全是一个鸡肋。因此,在 MySQL 8.0 的版本中已经完全移除了此功能,也就是说在 MySQL 8.0 之后就完全没有查询缓存这个概念和功能了。

3)如何选择数据库引擎

选择数据库引擎要从实际的业务情况入手,比如是否需要支持事务?是否需要支持外键?是否需要支持持久化?以及是否支持地理位置存储以及索引等方面进行综合考量。
我们最常用的数据库引擎是 InnoDB,它是 MySQL 5.5.5 之后的默认引擎,其优点是支持事务,且支持 4 种隔离级别。

  • 读未提交:也就是一个事务还没有提交时,它做的变更就能被其他事务看到;
  • 读已提交:指的是一个事务只有提交了之后,其他事务才能看得到它的变更;
  • 可重复读:此方式为默认的隔离级别,它是指一个事务在执行过程中(从开始到结束)看到的数据都是一致的,在这个过程中未提交的变更对其他事务也是不可见的。
  • 串行化:是指对同一行记录的读、写都会添加读锁和写锁,后面访问的事务必须等前一个事务执行完成之后才能继续执行,所以这种事务的执行效率很低。
    InnoDB 还支持外键、崩溃后的快速恢复、支持全文检索(需要 5.6.4+ 版本)、集群索引,以及地理位置类型的存储和索引等功能。
    MyISAM 引擎是 MySQL 原生的引擎,但它并不支持事务功能,这也是后来被 InnoDB 替代为默认引擎的主要原因。MyISAM 有独立的索引文件,因此在读取数据方面的性能很高,它也支持全文索引、地理位置存储和索引等功能,但不支持外键。
    InnoDB 和 MyISAM 都支持持久化,但 MEMORY 引擎是将数据直接存储在内存中了,因此在重启服务之后数据就会丢失,但它带来的优点是执行速度很快,可以作为临时表来使用。
    我们可以根据实际的情况设置相关的数据库引擎,还可以针对不同的表设置不同的数据引擎,只需要在创建表的时候指定 engine=引擎名称即可,SQL 代码如下:
create table student(id int primary key auto_increment,uname varchar(60),age int
) engine=Memory;

4)InnoDB 自增主键

在面试的过程中我们经常看到这样一道面试题:

在一个自增表里面一共有 5 条数据,id 从 1 到 5,删除了最后两条数据,也就是 id 为 4 和 5 的数据,之后重启的 MySQL 服务器,又新增了一条数据,请问新增的数据 id 为几?

我们通常的答案是如果表为 MyISAM 引擎,那么 id 就是 6,如果是 InnoDB 那么 id 就是 4。

但是这个情况在高版本的 InnoDB 中,也就是 MySQL 8.0 之后就不准确了,它的 id 就不是 4 了,而是 6 了。因为在 MySQL 8.0 之后 InnoDB 会把索引持久化到日志中,重启服务之后自增索引是不会丢失的,因此答案是 6,这个需要面试者注意一下。

5)小结

本文讲了 MySQL 数据库运行流程的几个阶段,先从连接器授权,再到分析器进行语法分析。如果是 MySQL 8.0 之前的 select 语句可能会先查询缓存,如果有缓存则会直接返回结果给客户端,否则会从分析器进入优化器生成 SQL 的执行计划,然后交给执行器调用操作引擎执行相关的 SQL,再把结果返回给客户端。我们还讲了最常见的三种数据库引擎 InnoDB、MyISAM、MEMORY,以及它们的利弊分析。最后讲了 InnoDB 在高版本(8.0)之后可以持久化自增主键的小特性,希望可以帮助到你。

Java 源码剖析(16)--浅谈MySQL 的运行机制相关推荐

  1. Python源码剖析[16] —— Pyc文件解析

    Python源码剖析[16] -- Pyc文件解析 2008-02-28 18:29:55|  分类: Python |举报 |字号 订阅 Python源码剖析 --Pyc文件解析 本文作者: Rob ...

  2. java hashset 实现_HashSet实现原理分析(Java源码剖析)

    本文将深入讨论HashSet实现原理的源码细节.在分析源码之前,首先我们需要对HashSet有一个基本的理解. HashSet只存储不同的值,set中是不会出现重复值的. HashSet和HashMa ...

  3. 老李推荐:第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用 1...

    老李推荐:第5章5节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 获取系统服务引用 上一节我们描述了monkey的命令处理入口函数run是如何调用optionPro ...

  4. 【java集合框架源码剖析系列】java源码剖析之ArrayList

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本. 本博客将从源码角度带领大家学习关于ArrayList的知识. 一ArrayList类的定义: public class Arr ...

  5. 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法

    注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...

  6. 交友盲盒源码h5开发浅谈

    寻找爱情一直是我们人类永恒的追求.有那么多的书.电影和故事都围绕着寻找真爱而展开,即使是在今天,我们仍然以某种方式执着于寻找我们的真爱,这一点也不奇怪.幸运的是,对于那些毫无希望的浪漫主义者来说,今天 ...

  7. java 字符串第一个字符_深入Java源码剖析之字符串常量

    字符串在Java生产开发中的使用频率是非常高的,可见,字符串对于我们而言非常关键.那么从C语言过来的同学会发现,在C中是没有String类型的,那么C语言要想实现字符串就必须使用char数组,通过一个 ...

  8. Java 源码剖析(13)--MyBatis 使用了哪些设计模式?

    MyBatis 使用了哪些设计模式 1)简介 2)工厂模式 3)建造者模式(Builder) 4)单例模式 5)适配器模式 6)代理模式 7)模板方法模式 8)装饰器模式 1)简介 MyBatis 的 ...

  9. python flask源码解析_浅谈flask源码之请求过程

    Flask Flask是什么? Flask是一个使用 Python 编写的轻量级 Web 应用框架, 让我们可以使用Python语言快速搭建Web服务, Flask也被称为 "microfr ...

最新文章

  1. Fedora 下安装Mplayer(添加源和解决错误问题)
  2. 《塞洛特傳說》道具系统
  3. 安装完Hadoop之后,命令行输入hadoop或hdfs却找不到命令的解决方法
  4. 社团的CTF逆向题WriteUp
  5. 计算机游戏88关,天天象棋88关怎么过 闯关模式第88关图文攻略
  6. 在线抠图工具:亲测有效
  7. php超星查课接口,这是一个可以查询超星课程的接口,请教一下该怎么用啊
  8. oracle获取序列跳号,Oracle sequence跳号知多少
  9. JavaWeb --第四章Maven详解
  10. dhs手术是什么意思_#下颌角手术# #磨骨瘦脸# 下颌角手术多少钱?
  11. 2018值得一看的GAN论文回顾
  12. android bu,Android请求权限之不再询问或禁止不再提示
  13. ul c语言,IMX6UL裸机实现C语言蜂鸣器实验
  14. 如何无信用卡申请谷歌云
  15. 有关错误:buffer i/o error on device fd0,logical block 0
  16. matlab读取excel、text文件 || xlsread textread
  17. 如何在云服务器上安装kali系统
  18. python语言程序设计习题
  19. 金蝶K3开发-工业单据显示物料图片
  20. 拍案叫绝的情报分析之图片挖掘

热门文章

  1. 抖音怎么拍视频能上热门推荐?
  2. SOLIDWORKS如何快速制作库特征
  3. Qt事件重写实现按住左键拖动移动控件,bool eventFilter(QObject *watched, QEvent *event)
  4. 解决阿里云oss文件上传部分MP4格式视频文件上传导致上传崩溃问题
  5. 连接语音服务器异常,“吃鸡”语音服务器异常是怎么回事?连麦上分的最大优点是什么?...
  6. Android vivo手机安装失败的解决方式
  7. 一个共通的viewModel搞定所有的编辑页面
  8. 鼠标、键盘单一受损的解决办法
  9. Win11 win10系统分区时出现defrag事件怎么解决?
  10. Windows中如何安装和使用binwalk