写在前面的话

脑子是个好东西,可惜的是一直没有搞懂脑子的内存删除机制是什么,所以啊,入行多年,零零散散的文章看了无数,却总是学习了很多也忘了很多。

痛定思痛的我决定从今天开始系统的梳理下知识架构,记录下零散的知识,方便温故知新的同时也顺便清除一些大脑空间用来学习更高深的技术。


目录

MySQL 基础

关系型数据库介绍

MySQL 介绍

MySQL 基础架构

MySQL 存储引擎

MySQL 支持哪些存储引擎?默认使用哪个?

MySQL 存储引擎架构了解吗?

MyISAM 和 InnoDB 的区别是什么?

MyISAM 和 InnoDB 如何选择?

MySQL 查询缓存

MySQL 事务

何谓事务?

何谓数据库事务?

并发事务带来了哪些问题?

SQL 标准定义了哪些事务隔离级别?

MySQL 的隔离级别是基于锁实现的吗?

MySQL 的默认隔离级别是什么?

MySQL 锁

表级锁和行级锁了解吗?有什么区别?

行级锁的使用有什么注意事项?

共享锁和排他锁呢?

意向锁有什么作用?

​编辑

InnoDB 有哪几类行锁?

参考


MySQL 基础

关系型数据库介绍

顾名思义,关系型数据库就是一种建立在关系模型的基础上的数据库。关系模型表明了数据库中所存储的数据之间的联系(一对一、一对多、多对多)。

关系型数据库中,我们的数据都被存放在了各种表中(比如用户表),表中的每一行就存放着一条数据(比如一个用户的信息)。

大部分关系型数据库都使用 SQL 来操作数据库中的数据。并且,大部分关系型数据库都支持事务的四大特性(ACID)。

有哪些常见的关系型数据库呢?

MySQL、PostgreSQL、Oracle、SQL Server、SQLite(微信本地的聊天记录的存储就是用的 SQLite) ......。

MySQL 介绍

MySQL 是一种关系型数据库,主要用于持久化存储我们的系统中的一些数据比如用户信息。

由于 MySQL 是开源免费并且比较成熟的数据库,因此,MySQL 被大量使用在各种系统中。任何人都可以在 GPL(General Public License) 的许可下下载并根据个性化的需要对其进行修改。MySQL 的默认端口号是3306

MySQL 基础架构

下图是 MySQL 的一个简要架构图,从下图你可以很清晰的看到客户端的一条 SQL 语句在 MySQL 内部是如何执行的。

从上图可以看出, MySQL 主要由下面几部分构成:

  • 连接器: 身份认证和权限相关(登录 MySQL 的时候)。
  • 查询缓存: 执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。
  • 分析器: 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。
  • 优化器: 按照 MySQL 认为最优的方案去执行。
  • 执行器: 执行语句,然后从存储引擎返回数据。 执行语句之前会先判断是否有权限,如果没有权限的话,就会报错。
  • 插件式存储引擎 : 主要负责数据的存储和读取,采用的是插件式架构,支持 InnoDB、MyISAM、Memory 等多种存储引擎。

MySQL 存储引擎

MySQL 核心在于存储引擎,想要深入学习 MySQL,必定要深入研究 MySQL 存储引擎。

MySQL 支持哪些存储引擎?默认使用哪个?

MySQL 支持多种存储引擎,你可以通过 show engines 命令来查看 MySQL 支持的所有存储引擎。

从上图我们可以查看出, MySQL 当前默认的存储引擎是 InnoDB。并且,所有的存储引擎中只有 InnoDB 是事务性存储引擎,也就是说只有 InnoDB 支持事务。

我这里使用的 MySQL 版本是 8.x,不同的 MySQL 版本之间可能会有差别。

MySQL 5.5.5 之前,MyISAM 是 MySQL 的默认存储引擎。5.5.5 版本之后,InnoDB 是 MySQL 的默认存储引擎。

你可以通过 select version() 命令查看你的 MySQL 版本。

 mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.27    |
+-----------+
1 row in set (0.00 sec)

你也可以通过 show variables like '%storage_engine%' 命令直接查看 MySQL 当前默认的存储引擎。

如果你只想查看数据库中某个表使用的存储引擎的话,可以使用 show table status from db_name where name='table_name'命令。

如果你想要深入了解每个存储引擎以及它们之间的区别,推荐你去阅读以下 MySQL 官方文档对应的介绍(面试不会问这么细,了解即可):

  • InnoDB 存储引擎详细介绍:https://dev.mysql.com/doc/refman/8.0/en/innodb-storage-engine.html 。
  • 其他存储引擎详细介绍:https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html 。

MySQL 存储引擎架构了解吗?

MySQL 存储引擎采用的是插件式架构,支持多种存储引擎,我们甚至可以为不同的数据库表设置不同的存储引擎以适应不同场景的需要。存储引擎是基于表的,而不是数据库。

并且,你还可以根据 MySQL 定义的存储引擎实现标准接口来编写一个属于自己的存储引擎。这些非官方提供的存储引擎可以称为第三方存储引擎,区别于官方存储引擎。像目前最常用的 InnoDB 其实刚开始就是一个第三方存储引擎,后面由于过于优秀,其被 Oracle 直接收购了。

MySQL 官方文档也有介绍到如何编写一个自定义存储引擎,地址:https://dev.mysql.com/doc/internals/en/custom-engine.html 。

MyISAM 和 InnoDB 的区别是什么?

MySQL 5.5 之前,MyISAM 引擎是 MySQL 的默认存储引擎,可谓是风光一时。

虽然,MyISAM 的性能还行,各种特性也还不错(比如全文索引、压缩、空间函数等)。但是,MyISAM 不支持事务和行级锁,而且最大的缺陷就是崩溃后无法安全恢复。

MySQL 5.5.5 之前,MyISAM 是 MySQL 的默认存储引擎。5.5.5 版本之后,InnoDB 是 MySQL 的默认存储引擎。

言归正传!咱们下面还是来简单对比一下两者:

1.是否支持行级锁

MyISAM 只有表级锁(table-level locking),而 InnoDB 支持行级锁(row-level locking)和表级锁,默认为行级锁。

也就说,MyISAM 一锁就是锁住了整张表,这在并发写的情况下是多么滴憨憨啊!这也是为什么 InnoDB 在并发写的时候,性能更牛皮了!

2.是否支持事务

MyISAM 不提供事务支持。

InnoDB 提供事务支持,实现了 SQL 标准定义了四个隔离级别,具有提交(commit)和回滚(rollback)事务的能力。并且,InnoDB 默认使用的 REPEATABLE-READ(可重读)隔离级别是可以解决幻读问题发生的(基于 MVCC 和 Next-Key Lock)。

关于 MySQL 事务的详细介绍,可以看看我写的这篇文章:MySQL 事务隔离级别详解open in new window。

3.是否支持外键

MyISAM 不支持,而 InnoDB 支持。

外键对于维护数据一致性非常有帮助,但是对性能有一定的损耗。因此,通常情况下,我们是不建议在实际生产项目中使用外键的,在业务代码中进行约束即可!

阿里的《Java 开发手册》也是明确规定禁止使用外键的。

 不过,在代码中进行约束的话,对程序员的能力要求更高,具体是否要采用外键还是要根据你的项目实际情况而定。

总结:一般我们也是不建议在数据库层面使用外键的,应用层面可以解决。不过,这样会对数据的一致性造成威胁。具体要不要使用外键还是要根据你的项目来决定。

4.是否支持数据库异常崩溃后的安全恢复

MyISAM 不支持,而 InnoDB 支持。

使用 InnoDB 的数据库在异常崩溃后,数据库重新启动的时候会保证数据库恢复到崩溃前的状态。这个恢复的过程依赖于 redo log 。

5.是否支持 MVCC

MyISAM 不支持,而 InnoDB 支持。

讲真,这个对比有点废话,毕竟 MyISAM 连行级锁都不支持。MVCC 可以看作是行级锁的一个升级,可以有效减少加锁操作,提高性能。

6.索引实现不一样。

虽然 MyISAM 引擎和 InnoDB 引擎都是使用 B+Tree 作为索引结构,但是两者的实现方式不太一样。

InnoDB 引擎中,其数据文件本身就是索引文件。相比 MyISAM,索引文件和数据文件是分离的,其表数据文件本身就是按 B+Tree 组织的一个索引结构,树的叶节点 data 域保存了完整的数据记录。

详细区别,推荐你看看我写的这篇文章:MySQL 索引详解open in new window。

MyISAM 和 InnoDB 如何选择?

大多数时候我们使用的都是 InnoDB 存储引擎,在某些读密集的情况下,使用 MyISAM 也是合适的。不过,前提是你的项目不介意 MyISAM 不支持事务、崩溃恢复等缺点(可是~我们一般都会介意啊!)。

《MySQL 高性能》上面有一句话这样写到:

不要轻易相信“MyISAM 比 InnoDB 快”之类的经验之谈,这个结论往往不是绝对的。在很多我们已知场景中,InnoDB 的速度都可以让 MyISAM 望尘莫及,尤其是用到了聚簇索引,或者需要访问的数据都可以放入内存的应用。

一般情况下我们选择 InnoDB 都是没有问题的,但是某些情况下你并不在乎可扩展能力和并发能力,也不需要事务支持,也不在乎崩溃后的安全恢复问题的话,选择 MyISAM 也是一个不错的选择。但是一般情况下,我们都是需要考虑到这些问题的。

因此,对于咱们日常开发的业务系统来说,你几乎找不到什么理由再使用 MyISAM 作为自己的 MySQL 数据库的存储引擎。

MySQL 查询缓存

执行查询语句的时候,会先查询缓存。不过,MySQL 8.0 版本后移除,因为这个功能不太实用

my.cnf 加入以下配置,重启 MySQL 开启查询缓存

query_cache_type=1
query_cache_size=600000

MySQL 执行以下命令也可以开启查询缓存

set global  query_cache_type=1;
set global  query_cache_size=600000;

如上,开启查询缓存后在同样的查询条件以及数据情况下,会直接在缓存中返回结果。这里的查询条件包括查询本身、当前要查询的数据库、客户端协议版本号等一些可能影响结果的信息。(查询缓存不命中的情况:(1))因此任何两个查询在任何字符上的不同都会导致缓存不命中。此外,(查询缓存不命中的情况:(2))如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、MySQL 库中的系统表,其查询结果也不会被缓存。

查询缓存不命中的情况:(3)缓存建立之后,MySQL 的查询缓存系统会跟踪查询中涉及的每张表,如果这些表(数据或结构)发生变化,那么和这张表相关的所有缓存数据都将失效。

缓存虽然能够提升数据库的查询性能,但是缓存同时也带来了额外的开销,每次查询后都要做一次缓存操作,失效后还要销毁。 因此,开启查询缓存要谨慎,尤其对于写密集的应用来说更是如此。如果开启,要注意合理控制缓存空间大小,一般来说其大小设置为几十 MB 比较合适。此外,还可以通过 sql_cache 和 sql_no_cache 来控制某个查询语句是否需要缓存:

select sql_no_cache count(*) from usr;

MySQL 事务

何谓事务?

我们设想一个场景,这个场景中我们需要插入多条相关联的数据到数据库,不幸的是,这个过程可能会遇到下面这些问题:

  • 数据库中途突然因为某些原因挂掉了。
  • 客户端突然因为网络原因连接不上数据库了。
  • 并发访问数据库时,多个线程同时写入数据库,覆盖了彼此的更改。
  • ......

上面的任何一个问题都可能会导致数据的不一致性。为了保证数据的一致性,系统必须能够处理这些问题。事务就是我们抽象出来简化这些问题的首选机制。事务的概念起源于数据库,目前,已经成为一个比较广泛的概念。

何为事务? 一言蔽之,事务是逻辑上的一组操作,要么都执行,要么都不执行。

事务最经典也经常被拿出来说例子就是转账了。假如小明要给小红转账 1000 元,这个转账会涉及到两个关键操作,这两个操作必须都成功或者都失败。

  1. 将小明的余额减少 1000 元
  2. 将小红的余额增加 1000 元。

事务会把这两个操作就可以看成逻辑上的一个整体,这个整体包含的操作要么都成功,要么都要失败。这样就不会出现小明余额减少而小红的余额却并没有增加的情况。

何谓数据库事务?

大多数情况下,我们在谈论事务的时候,如果没有特指分布式事务,往往指的就是数据库事务

数据库事务在我们日常开发中接触的最多了。如果你的项目属于单体架构的话,你接触到的往往就是数据库事务了。

那数据库事务有什么作用呢?

简单来说,数据库事务可以保证多个对数据库的操作(也就是 SQL 语句)构成一个逻辑上的整体。构成这个逻辑上的整体的这些数据库操作遵循:要么全部执行成功,要么全部不执行 。

# 开启一个事务
START TRANSACTION;
# 多条 SQL 语句
SQL1,SQL2...
## 提交事务
COMMIT;

另外,关系型数据库(例如:MySQLSQL ServerOracle 等)事务都有 ACID 特性:

  1. 原子性Atomicity) : 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  2. 一致性Consistency): 执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  3. 隔离性Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  4. 持久性Durabilily): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

【MySQL】MySQL进阶之路(二)MySQL重要知识点散记相关推荐

  1. 毛毛Python进阶之路6——MySQL 数据库(二)

    毛毛Python进阶之路6--MySQL 数据库(二) 一.对于自增 show create table 表名; # 查看表是怎样创建的. show create table 表名\G; #将某个表旋 ...

  2. ES7、ES8、ES9、ES10、ES11、ES12、ES13、ES14(ES进阶之路二)

    简介 JavaScript是世界上发展最快的编程语言之一,不仅可以用于编写运行在浏览器的客户端程序,随着Node.js的发展,JavaScript也被广泛应用于编写服务端程序.而随着JavaScrip ...

  3. 音视频开发成长之路—进阶之路3个重要知识点丨WebRTC丨FFmpeg丨SRS流媒体服务器丨C++音视频丨嵌入式音视频

    音视频开发成长之路-进阶之路3个重要知识点 视频讲解如下,点击观看: 音视频开发成长之路-进阶之路3个重要知识点丨WebRTC丨FFmpeg丨SRS流媒体服务器丨C++音视频丨嵌入式音视频 音视频高级 ...

  4. MySQL学习整理-码农进阶之路(二)

    二:MySQL基础架构 2.1硬盘 机械硬盘由磁盘片.磁头和磁头臂等组成,一次IO的流程大致是寻道[磁头臂移动]->旋转[获取扇区]->读取,一次大概9ms,主要开销在寻道和旋转上,读取1 ...

  5. mysql limit 菜鸟_MySQL之二---MySQL菜鸟入门“秘籍”

    一.MySQL简介 1.什么是数据库 ? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不 ...

  6. ES进阶之路二(ES7-ES12)

    简介 JavaScript是世界上发展最快的编程语言之一,不仅可以用于编写运行在浏览器的客户端程序,随着Node.js的发展,JavaScript也被广泛应用于编写服务端程序.而随着JavaScrip ...

  7. 【进阶之路】Mysql与Oracle的区别

    导言 大家好,我是南橘,从接触java到现在也有差不多两年时间了,两年时间,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西.知识越分享越值钱,我这段时间总结 ...

  8. mysql 开发进阶篇系列 41 mysql日志之慢查询日志

    一.概述 慢查询日志记录了所有的超过sql语句( 超时参数long_query_time单位 秒),获得表锁定的时间不算作执行时间.慢日志默认写入到参数datadir(数据目录)指定的路径下.默认文件 ...

  9. python npv 计算公式_python数据分析进阶之路(二)----Numpy进阶

    简单应用 矩阵创建及运算 1.手动创建矩阵 np.mat('str') 利用mat('字符串')函数创建矩阵,其中字符串的 表示中,矩阵的行与行之间用分号隔开,行内的元素之间用空格隔开. b = np ...

  10. 面向对象进阶-反射(二)重要知识点

    # 面向对象的进阶# 其他常用模块# 作业 考试题# 网络编程 2天# ftp作业 # class A:pass# class B(A):pass# a = A()# print(isinstance ...

最新文章

  1. c语言:输出一个菱形图
  2. 用bert来训练quoras question pairs的代码仓
  3. win7隐藏linux分区工具,传授win7系统用组策略把分区隐藏掉的处理对策
  4. MyEclipse优化设置(最详细版本)
  5. PHP递归创建多级目录(一道面试题的解题过程)
  6. 快速解决工作中遇到经典的括号匹配问题
  7. DNS原理及其解析过程 精彩剖析
  8. python工资高还是java-python工资高还是java
  9. mysql统计一张表中条目个数的方法
  10. 我的世界HMCL安装与使用
  11. 2016年考研数学一真题pdf ​​​
  12. ZUC加密算法实现-软件版本Java
  13. Automate your Android app testing
  14. 学习GIT的一个小游戏
  15. web zxr10 中兴 路由器_中兴 ZXR10与思科路由器互联问题-路由器
  16. 重装系统(无法开机时候操作方法)
  17. 机器学习 - 人脸识别
  18. ffmpeg sdk 视频合成 音视频截取
  19. windows安装linux子系统,并装在其他系统盘的方法
  20. 主攻文推荐攻守都有系统_【图片】【推文】一些喜欢的主攻文_主攻文吧_百度贴吧...

热门文章

  1. 读取界面信息以及文本分割按键精灵
  2. 零售商场无线覆盖解决方案
  3. “我只警告一次,下次我会直接忽略你发的垃圾,懂?”Linus 精彩炮轰语录集锦
  4. PyTorch学习笔记-Convolution Layers与Pooling Layers
  5. 大连大学2022年11月程序设计竞赛(同步赛) 原创F题题解
  6. flarum安装图片幻灯片fancybox插件
  7. 我们身边40岁的Android程序员的“晚年“
  8. CSS中div平行移动,即轻微动画效果的使用
  9. HDU 4499 DFS
  10. html ol li 数字点去掉,HTML 去除 li 前面的小黑点及 ul、li 部分属性介绍