这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天
目录
- 经典案例
- 关键技术
RDBMS:关系型数据库管理系统(relational database management system)
经典案例 -- 抖音红包雨
graph LR
抖音 --> 羊老师
- 从抖音账户上扣除一个小目标
- 给羊老师的账户加上一个小目标
UPDATE account__table SET balance = balance - '一个小目标' WHERE name = '抖音';
UPDATE account__table SET balance = balance + '一个小目标' WHERE name = '羊老师';
事务
- 是由一组SQL语句组成的一个程序执行单元Unit,需要满足ACID特性
BEGIN;
UPDATE account__table SET balance = balance - '一个小目标' WHERE name = '抖音';
UPDATE account__table SET balance = balance + '一个小目标' WHERE name = '羊老师';
COMMIT;
-
原子性:假设抖音已经扣除了一个亿,而此时服务器崩了,还没来得及给羊老师账户加上一个亿,所以两个操作要么同时成功,要么同时失败,才满足原子性
-
一致性:假设抖音账户只有0.5亿,但是扣减一个亿的操作成功了。所以为了保证一致性,每个操作都必须是合法的,账户信息应该从一个有效的状态变为另外一个有效的状态
-
隔离性:假设羊老师从抖音抢了一个亿,又从头条抢了一个亿,两个转账同时进行,假设羊老师账户余额为0,最后转账操作完成,更新羊老师账户余额,却只有一个亿。所以两个操作在对一个账户并发进行操作时,应该是互相不影响的(表现结果像串行,执行可能是并行),才能满足隔离性
-
持久性:抖音的账户已经成功扣除一个亿,而羊老师账户也成功加上了一个亿,此时还没有成功写到磁盘上,如果服务器此时挂掉了(寄)。所以在操作更新之后,更新的结果应该永久性的保留下来,不会因为宕机等问题而丢失数据
关键技术
解析器(Parser)
优化器
Undo Log
如何将数据库回退到修改之前的状态?
- SQL
Insert into users(id, name, phone_num) value(100, jim, 123456);
- Undo Log
Delete from users where id = 100;
- SQL
Update users set phone_num = 123123 where id = 100;
- Undo Log
Update users set phone_num = 123456 where id = 100;
Isolation 与锁
- 同时读: Share Lock
- 同时写:Exclusive Lock
- 有读有写: MVCC
- 读写互不阻塞
- 降低死锁概率
- 实现一致性读 先给读老版本的数据,然后写入,继而更新读的数据
Durability 与 Redo Log
如果保证事务结束后,对数据的修改永久保存?
- 方案一:事务提前写入页面写盘
- 代价:随机IO、写放大
- 方案二:WAL(Write-ahead logging)
- redo log是物理日志,记录的是页面的变化,保证事务的持久化,如果数据写入磁盘前故障,重启MySQL后会根据redo log重做