Skip to content

Commit

Permalink
mysql
Browse files Browse the repository at this point in the history
  • Loading branch information
gongluck committed Jan 11, 2024
1 parent 003d425 commit 10e2aa4
Show file tree
Hide file tree
Showing 9 changed files with 297 additions and 0 deletions.
30 changes: 30 additions & 0 deletions mysql/1.sql.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SQL 优化

- [SQL 优化](#sql-优化)
- [SQL 执行过程](#sql-执行过程)
- [问题定位](#问题定位)
- [优化](#优化)
- [SQL 注入](#sql-注入)

## SQL 执行过程

![SQL执行过程](./sql.png)

## 问题定位

- 满查询日志
- explain 分析执行计划

## 优化

- 表设计,避免数据冗余和重复计算
- 合理设计索引
- 分库分表,减少数据量,减小查询范围

## SQL 注入

- 用户参数中包含了 SQL 语句,修改了原 SQL 的意图
- 避免方法
- 预编译,?号占位符
- 正则表达式过滤参数
- 过滤转义
21 changes: 21 additions & 0 deletions mysql/2.view.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 视图

- [视图](#视图)
- [视图定义](#视图定义)
- [优点](#优点)

## 视图定义

- 一种虚拟表,逻辑上的表,不包含数据
- 使用 SQL 定义
```sql
create view_name as <SQL>
```
- 通过视图可以展现基表全部或部分数据
- 通常用于查询,增删改会有限制

## 优点

- 简单可复用,隐藏基表复杂的 SQL
- 安全
- 数据独立,屏蔽基表数量、表结构的变化
65 changes: 65 additions & 0 deletions mysql/3.index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# 索引

- [索引](#索引)
- [索引定义](#索引定义)
- [使用索引的场景](#使用索引的场景)
- [不需使用索引的场景](#不需使用索引的场景)
- [索引失效](#索引失效)
- [索引的代价](#索引的代价)
- [主键索引](#主键索引)
- [唯一索引](#唯一索引)
- [覆盖索引](#覆盖索引)
- [索引下推](#索引下推)

## 索引定义

- 一种有序的存储结构
- 按照单个或多个列的值进行排序
- 对应着一个 B+树
- 提升搜索效率

## 使用索引的场景

- where
- group by
- order by

## 不需使用索引的场景

- 没有 where/group by/order by
- 区分度不高的列
- 经常修改的列
- 数据量少

## 索引失效

- 左模糊匹配
- 索引参与运算,使用函数、表达式运算、隐式转换
- where or 有非索引字段
- 不符合最左匹配原则

## 索引的代价

- B+树空间
- 维护 B+树的时间

## 主键索引

- 非空唯一索引
- 一个表只有一个主键索引,primary key 修饰或者使用第一个非空唯一索引作为主键,或者自动生成主键
- 包含所有行信息

## 唯一索引

- 索引列不能出现重复值,可以有 null 值
- unique 修饰
- 只包含索引信息和主键信息

## 覆盖索引

- 直接通过辅助索引就能获取全部要查询的数据,无需回表查询
- 在 select from 之间尽量列出所有需要的字段,如果字段恰好都在辅助索引 B+树中,就会使用覆盖索引

## 索引下推

- 在索引的遍历过程中,对索引中包含字段先做判断,直接将不满足的数据行排除,从而减少回表的次数
15 changes: 15 additions & 0 deletions mysql/4.B+tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# B+树

- [B+树](#b树)
- [B+树特点](#b树特点)

## B+树特点

- 多路平衡搜索树
- 多路,降低层高,减少磁盘 IO
- 平衡,增删改通过平衡确保搜索时间稳定
- 搜索,有序
- 所有叶子节点在同一层
- 叶子节点间有双向链表连接,方便范围查询和降低磁盘 IO
- 节点大小固定,16K
- 非叶子节点记录索引信息,叶子节点存放数据信息
75 changes: 75 additions & 0 deletions mysql/5.transaction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 事务

- [事务](#事务)
- [事务特性](#事务特性)
- [原子性](#原子性)
- [一致性](#一致性)
- [隔离性](#隔离性)
- [持久性](#持久性)
- [隔离级别](#隔离级别)
- [读未提交](#读未提交)
- [读已提交](#读已提交)
- [可重复读](#可重复读)
- [可串行化](#可串行化)
- [脏读](#脏读)
- [不可重复读](#不可重复读)
- [幻读](#幻读)

## 事务特性

### 原子性

- 事务中的所有操作要么全部成功执行,要么全部回滚
- 如果在事务执行过程中发生错误,会将已经执行的操作进行回滚,保持数据一致性

### 一致性

- 事务开始前和结束后,数据库的完整性约束没有被破坏
- 在事务执行过程中对数据的修改必须符合预定义的规则,以保证数据的有效性和正确性

### 隔离性

- 每个事务在并发执行时都应该相互隔离,并且不应该互相干扰
- 一个事务在提交之前对其他事务是不可见的,防止了读取到未提交或部分提交的数据

### 持久性

- 一旦事务提交成功后,其所做的修改就会永久保存到数据库中,并且不能被撤销
- 即使在系统故障或断电情况下,也能够保证数据不会丢失

## 隔离级别

### 读未提交

- 一个事务可以读取另一个事务尚未提交的数据
- 这可能导致脏读:一个事务读取了另一个事务尚未提交的数据。如果该事务回滚,读取到的数据将无效

### 读已提交

- 一个事务只能读取另一个事务已提交的数据
- 解决了脏读问题,但可能导致不可重复读:在一个事务中,多次读取同一数据,由于其他事务的修改,导致返回的数据不一致

### 可重复读

- 一个事务在其生命周期内多次读取同一数据,数据始终保持一致
- 解决了不可重复读问题,但可能导致幻读:在一个事务中,两次查询范围相同的记录,由于其他事务的插入或删除操作,导致返回的记录数量不一致

### 可串行化

- 事务被强制按顺序执行,完全避免了脏读、不可重复读和幻读等问题
- 牺牲了并发性能,因为事务必须按顺序执行

## 脏读

- 一个事务可以读到其它事务未提交的状态

## 不可重复读

- 一个事务中两次读的结果不同
- 因为读以提交是读最新版本的数据,最新的数据可能被其它事务修改

## 幻读

- 一个事务中两次读取同一个范围的结果不同
- 因为当前读和快照读不一致造成
- 解决:把快照读改成当前读,可重复读下范围查询会加上 gap 锁
52 changes: 52 additions & 0 deletions mysql/6.dead-lock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# 死锁

- [死锁](#死锁)
- [死锁原因](#死锁原因)
- [锁类型](#锁类型)
- [S 锁](#s-锁)
- [X 锁](#x-锁)
- [gap 锁](#gap-锁)
- [auto-inc 锁](#auto-inc-锁)
- [插入意向锁](#插入意向锁)
- [解决死锁](#解决死锁)

## 死锁原因

- 多个事务并发执行时因争夺资源而造成互相等待
- 相反顺序加锁
- 外键和触发器等隐式给子表加锁
- S 锁和 X 锁冲突
- 已经获取 gap 锁后,尝试获取插入意向锁造成等待

## 锁类型

### S 锁

- 可串行化中,查询自动加 S 锁
- 可重复读中,查询可以手动加 S 锁

### X 锁

- 查询中,使用 for update 加 X 锁
- 删除或更新自动加 X 锁

### gap 锁

- 可重复读中,范围操作或未命中加 gap 锁,避免幻读

### auto-inc 锁

- 插入时的特殊锁,插入后马上释放

### 插入意向锁

- 插入意图锁是一种间隙锁,在执行插入之前设置
- 插入意向锁只会和间隙锁或者 Next-key 锁冲突

## 解决死锁

- 修改 SQL,调整加锁顺序
- 降低隔离级别
- 添加合理的索引,不走索引会全表加锁
- 避免大事务
- 避免同一个时间点执行多个操作同一表的事务
30 changes: 30 additions & 0 deletions mysql/7.mvcc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# MVCC

- [MVCC](#mvcc)
- [MVCC 特点](#mvcc-特点)
- [关键数据结构](#关键数据结构)
- [read view](#read-view)
- [聚集索引中隐藏的列](#聚集索引中隐藏的列)

## MVCC 特点

- 一致性非锁定读
- 解决隔离级别中的读优化
- 读已提交中,mvcc 读取最新已提交版本
- 可重复读中,mvcc 读取本事务开始前一个版本

## 关键数据结构

### read view

- m_ids,创建 read view 时,启动未提交的事务 id
- min_trx_id,创建 read view 时,启动未提交的事务 id 中的最小值
- max_trx_id,创建 read view 时,预分配给下一个事务的 id
- creator_trx_id,创建该 read view 的事务 id
- 读已提交中,每次读取操作创建 read view
- 可重复读中,每次开始事务创建 read view

### 聚集索引中隐藏的列

- trx_id,记录修改事务 id
- roll_pointer,记录回滚版本在 undolog 中的位置
9 changes: 9 additions & 0 deletions mysql/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# MySQL

- [x] [SQL 优化](./1.sql.md)
- [x] [视图](./2.view.md)
- [x] [索引](./3.index.md)
- [x] [B+树](./4.B+tree.md)
- [x] [事务](./5.transaction.md)
- [x] [死锁](./6.dead-lock.md)
- [x] [MVCC](./7.mvcc.md)
Binary file added mysql/sql.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 10e2aa4

Please sign in to comment.