深入理解RDBMS | 青训营笔记

89 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记

一条SQL的一生

sql生命周期.png

查询解析

首先将文本解析成结构化数据,即抽象语法树 解析器一般分为词法分析、语法分析、语义分析等步骤。

词法分析: 一条 SQL 语句有多个字符串组成,首先要提取关键字,比如 > select,提出查询的表,提出字段名,提出查询条件等等。将一条SQL语句对应的字符串分割为一个个token,这些token可以简单分类。

语法分析: 主要就是判断你输入的 sql 是否正确,是否符合 MySQL 的语法。把词法分析的结果转为语法树。根据token序列匹配不同的语法规则。根据语法规则匹配SQL语句的关键字,最终输出 一个结构化的数据结构。

查询优化

比如说select * from a, b, c where a.a1 = b.a1 and a.a1 = c.b1;这条sql语句,我有三种连接方式。

  1. 可以先a,b表连接后再与c表连接
  2. 可以先a,c表连接后再与b表连接
  3. 可以先c,b表连接后再与a表连接 用哪种方式,这就是查询优化做的事。下面有一些基本的优化方法。
  4. 条件化简:比方说a>5 and a<b and b=1这个条件可以直接化为False
  5. 表连接优化:总是小表先进行连接
  6. Scan优化:唯一索引、普通索引、全表扫描
  7. 基于代价的优化(CBO Cost Base Optimizer):一个查询有多种执行方案,CBO会选择其中代价最低的方案去真正的执行。

查询执行

查询执行.png
每个Operator调用Next操作,访问下层Operator,获得下层Operator返回的一行数据,经过计算之后,将这行数据返回给上层。但这有个问题,就是一行一行数据的操作,效率不高。 所以有了以下方案,每个Operator每次操作计算不再是一行数据,而是一批数据(Batch N行数据),计算完成后向上层算子返回一个Batch。

存储引擎

MyISAM和InnoDB的区别

1.是否支持行级锁

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

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

2.是否支持事务

MyISAM 不提供事务支持。

InnoDB 提供事务支持,具有提交(commit)和回滚(rollback)事务的能力。

3.是否支持外键

MyISAM 不支持,而 InnoDB 支持。

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

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

MyISAM 不支持,而 InnoDB 支持。

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

mySQL InnoDB 引擎使用 redo log(重做日志)  保证事务的持久性,使用 undo log(回滚日志)  来保证事务的原子性

MySQL InnoDB 引擎通过 锁机制MVCC 等手段来保证事务的隔离性( 默认支持的隔离级别是 REPEATABLE-READ )。

保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。

5.是否支持 MVCC

MyISAM 不支持,而 InnoDB 支持。

MVCC 可以看作是行级锁的一个升级,可以有效减少加锁操作,提高性能。

事务引擎

Atomicity与Undo Log

Undo Log是逻辑日志,记录的是数据的增量变化。利用Undo Log可以进行事务回滚,从而保证事务的原子性。同时也实现的多版本并发控制(MVCC), 解决读写冲突和一致性读问题。

Isolation与锁

Mysql主要有两种锁,共享锁(读锁),排它锁(写锁)。 如果一个数据拥有共享锁,则可以重复叠加共享锁,而一个数据儿拥有排它锁就不能再叠加任何锁。

Ioslation 与 MVCC

MVCC的意义

  • 读写互不阻塞
  • 降低死锁概率
  • 实现一致性读 Undo Log在MVCC的作用
  • 每个事务有一个单调递增的事务ID
  • 数据页的行记中包含了DB_ROW_ID,DB_TRX_ID,DB_ROLL_PTR;
  • DB_ROLL_PTR将数据行的所有快照记录都通过链表的结构串联起来。

Durability与Redo Log

通过Redo Log保障数据持久性,Redo Log记录页面的变化,在事务成功,并将数据成功写入磁盘后删除,如果数据写入磁盘前发生故障,重启MySQL后会根据redo Log重做。