《数据库》

一、事务

概念

事务的定义:满足 ACID 特性的一组操作。(ACID:酸)

在关系数据库中,一个事务可以是一条 SQL 语句、一组 SQL 语句或整个程序。使用 Commit 提交一个事务,使用 Rollback 进行回滚。

image-20210502172804098

ACID

1. 原子性(Atomicity)

事务是不可分割的最小单位,事务的所有操作要么全部提交成功,要么全部失回滚。

2. 一致性(Consistency)

在事务执行前后,所有事务对同一个数据的读取结果都是相同的。

3. 隔离性(Isolation)

一个事务所做的修改在最终提交以前,对其它事务是不可见的。

4. 持久性(Durability)

一个事务被提交,所做的修改会永远保存到数据库中。即使系统崩溃,事务执行的结果也不会丢失。

ACID靠什么保证

  • A:靠 回滚日志(Undo Log)实现。
  • C:靠 其他其他三大特性AID 实现。
  • I: 靠 锁 和 MVCC 实现。
  • D:靠 重做日志(Redo Log)实现。系统发生崩溃使用重做日志(Redo Log)进行恢复。

二、事务并发带来的问题

在并发环境下,事务的隔离性很难保证,因此会出现很多事务并发的问题。

丢失修改

定义:一个事务的更新操作被另外一个事务的更新操作所替换

例如:T1 和 T2 两个事务都对一个数据进行修改,T1 先修改并提交生效,T2 随后修改,T2 的修改覆盖了 T1 的修改。

image-20210502173807565

脏读

定义:一个事务读到另一个事务未提交的数据

例如:T1 修改一个数据但未提交,T2 随后读取这个数据。如果 T1 撤销了这次修改,那么 T2 读取的数据是脏数据。

image-20210502173927227

不可重复读

定义:一个事务连续读取两次的数据不一致。因为在第一次读取后,另一个事务对数据进行了修改。

例如:T2 读取一个数据,T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。

image-20210502174030318

幻读

定义:幻读是不可重复读的一种情况。第一次读取时,数据不存在;第二次读取,数据出现了

产生并发不一致问题的主要原因是破坏了事务的隔离性,解决方法是通过并发控制来保证隔离性。并发控制可以通过封锁来实现,但是封锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更轻松的方式处理并发一致性问题。

三、封锁

封锁粒度

封锁的大小称为封锁粒度。封锁粒度越小,系统的并发程度就越高,系统开销也越大。

封锁类型

按粒度分类
1. 行级锁

对表上的某一行或多行加锁。

2. 表级锁

对整张表加锁。

3. 记录锁

Record Lock,属于行锁的一种,对索引项加锁。其他事务不能修改加锁项。

4. 间隙锁

Gap Lock,对索引项之间的间隙加锁,但不包含索引项本身。其他事务不能在加锁范围内插入数据,防止幻读。

5. Next-key Lock

索引项索引项之间的间隙加锁。是记录锁和间隙锁的结合。可解决幻读问题。

按属性分类
1. 读写锁

作用:读写锁是行级锁。

原理:分为互斥锁和共享锁。

  • 互斥锁(Exclusive),简写为 X 锁,又称写锁
  • 共享锁Shared),简写为 S 锁,又称读锁

有以下两个规定:

  • 一个事务对数据对象 A 加了 写锁,就可以对 A 进行读取写入。加锁期间其它事务不能对 A 加其他的锁
  • 一个事务对数据对象 A 加了 读锁,可以对 A 进行读取操作,但是不能进行写入操作。加锁期间其它事务对 A 加读锁,但是不能加 写锁
2. 意向锁

作用:意向锁(Intention Locks)是表级锁。

原理:意向锁 在 读写锁 之上引入了 表级互斥锁表级共享锁IX/IS )。

通过引入意向锁,事务想要 对表加 X锁,需要先检测是否有其它事务对表加了 X/IX/S/IS 锁。如果加了就表示有其它事务正在使用这个表或者表中某一行,因此事务 加 X锁 失败

封锁协议

1. 三级封锁协议

一级封锁协议

事务修改数据时必须加 X 锁,直到事务结束才释放 X 锁

解决丢失修改问题。

二级封锁协议

在一级的基础上,要求读取数据时必须加 S 锁读取完马上释放 S 锁

解决脏读问题。

三级封锁协议

在二级的基础上,要求读取数据时必须加 S 锁,直到事务结束才释放 S 锁

解决不可重复读的问题。

2. 两段锁协议

在加锁阶段,事务只能加锁,不能解锁。直到事务释放第一个锁,就进入解锁阶段,此阶段 事务只能解锁,不能再加锁。

MySQL 隐式与显式锁定

隐式锁定定义:MySQL 的 InnoDB 存储引擎采用两段锁协议,会根据隔离级别在需要的时候自动加锁,锁只有在执行 commit 或rollback 的时候才会释放,并且所有的锁在同一时刻被释放

显示锁定定义:和隐式锁定相反。

四、隔离级别

未提交读

READ UNCOMMITTED,简称 RU 。

一个事务未提交的数据,对其它事务是可见的。

已提交读

READ COMMITTED,简称 RC 。

一个事务未提交的数据,对其它事务是不可见的。

可重复读

REPEATABLE READ,简称 RR 。

一个事务多次读取同一数据的结果是一样的。

串行化

SERIALIZABLE,简称 SE 。

强制事务串行执行,多个事务互不干扰,不会出现并发一致性问题。

image-20210503125855130

InnoDB 实现 隔离级别

  • RU:事务读取时,不加锁
  • RC:事务读取时,加 行级 S 锁,一旦读完,立刻释放
  • RR:事务读取时,加 行级 S 锁,直到事务结束,才释放
  • SE:事务读取时,加 表级 S 锁,直到事务结束,才释放

五、多版本并发控制

多版本并发控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现已提交读可重复读这两种隔离级别。

原理:事务的修改操作会生成一个数据快照。在事务进行读取操作时,只能读取已经提交的快照。解决脏读和不可重复读问题。主要用于 RC 和 RR 级别。

  • 实际使用 [CAS版本控制] 和 [读写分离] 的思想

快照读与当前读

1. 快照读

SELECT 操作是快照读不加锁

2. 当前读

增删改操作 是 当前读加锁读取数据库里最新的数据

六、关系数据库设计理论

函数依赖

记 A->B 表示 A 函数决定 B函数,也表示 B 函数依赖于 A函数。

异常

以下的学生课程关系的函数依赖为 {Sno, Cname} -> {Sname, Sdept, Mname, Grade},键码为 {Sno, Cname}。也就是说,确定学生和课程之后,就能确定其它信息。

SnoSnameSdeptMnameCnameGrade
1学生-1学院-1院长-1课程-190
2学生-2学院-2院长-2课程-280
2学生-2学院-2院长-2课程-1100
3学生-3学院-2院长-2课程-295

不符合范式的关系,会产生很多异常,主要有以下四种异常

  • 冗余数据:例如 学生-2 出现了两次。
  • 修改异常:修改了一个记录中的信息,但是另一个记录中相同的信息却没有被修改。
  • 删除异常:删除一个信息,那么也会丢失其它信息。例如删除了 课程-1 需要删除第一行和第三行,那么 学生-1 的信息就会丢失。
  • 插入异常:例如想要插入一个学生的信息,如果这个学生还没选课,那么就无法插入。

范式

范式理论是为了解决以上提到四种异常。

高级别范式的依赖于低级别的范式,1NF 是最低级别的范式。

1. 第一范式 (1NF)

属性不可分。

2. 第二范式 (2NF)

非主属性完全依赖于键码。

3. 第三范式 (3NF)

非主属性不传递依赖于键码。

七、ER 图

Entity-Relationship,有三个组成部分:实体、属性、联系。

Eg:教学系统 ER 图

image-20210503221734523 image-20210503141956991
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值