数据库系统:视图与事务

视图与事务

视图

定义

从一个或多个表(或视图)导出的表。视图在数据库系统中仅存放创建视图的语句,不存放视图对应的数据。

作用

  1. 从用户的角度看:使用户能以多种角度看待同一数据库模式、简化用户操作、更清晰地表达查询。
  2. 从系统的角度看:对数据库内的数据提供了一定的安全保护、提供了逻辑独立性。

基本语法

创建视图

create view <viewName> [(<columnName1>)] as
	<subQuery>
[with check option]

其中with check option能够在对视图进行更新操作时进行检查,只有该更新操作满足<subQuery>中的条件时,才允许视图被更新(视图的更新实质上是基本表的更新)。


事务

ACID四特性

A(atomatic)原子性:要求事务中的所有操作要么都做,要么都不做。若在执行过程中发生错误,会恢复到事务开始前的状态。由恢复管理模块完成。

C(consistency)一致性:要求事务的结果具有实体完整性(主码唯一且不为null)、参照完整性(外码必须来自参照的主码,或者为null)、用户自定义完整性。由程序员实现。

I(isolation)隔离性:事务与事务之间不会相互影响,由并发控制模块完成。

D(durability)持久性:事务执行结束后,对数据库造成的数据改变是持久的,即使数据库遇到故障也是如此。由恢复管理模块完成。

事务并发

优点导致的问题
提高系统吞吐量、减少平均响应时间读脏数据、不可重复读、丢失更新
  1. 冲突操作:作用于相同对象上的操作,且不全为读
  2. 冲突等价:一个调度S通过交换非冲突操作,得到令一调度S’
  3. 冲突可串行化:一个调度与串行调度冲突等价
  4. 优先图:G(V,E),其中顶点表示事务,边表示冲突操作的先后次序。若图中存在环(判断方法:DFS、拓补排序),则说明冲突不可串行化,否则冲突可串行化。

小练习

假设3个事务T1,T2,T3的操作按调度S1执行:
S1:R2(A) R1(B) W2(A) R3(A) W1(B) R3(A) R2(B) W2(B)
请画出优先图。

思路:优先图的顶点为事务T1 T2 T3
在这里插入图片描述

然后添加边集。边为事务的冲突操作先后次序,由先指向后,因此我们需要寻找冲突操作。

发生在A上的操作:
S1:R2(A) R1(B) W2(A) R3(A) W1(B) R3(A) R2(B) W2(B)

观察每一对操作,得到冲突操作:
R2(A) W2(A)
R2(A) R3(A) ··· T2->T3
R2(A) R3(A)
W2(A) R3(A) ··· T2->T3
W2(A) R3(A) ··· T2->T3
R3(A) R3(A)
因此在优先图上添加一条T2->T3的边。

同理,通过观察发生在B上的操作,在优先图上添加一条T1->T2的边。

最终得到优先图:
在这里插入图片描述
既然有边,那就说明存在冲突操作。那么根据优先图可以得到一个等价的串行调度:T1->T2->T3。

即S1: R1(B) W1(B) R2(A) W2(A) R2(B) W2(B) R3(A) R3(A)

基于封锁的协议

在事务对数据对象进行操作之前,必须根据读、写需要申请锁。若无法得到锁,则一直等待。

锁有两种基本的类型:共享锁(shared lock)、排他锁(exclusive lock)。即S锁和X锁。并且通过基本锁类型的相容性矩阵来控制申请请求。

但是仅仅这样,仍然会出现许多问题。

于是提出两阶段封锁协议,并在此基础上形成与采用严格两阶段封锁协议以及强两阶段封锁协议。

两阶段封锁协议:将事务的执行过程分为两个阶段,前一阶段只能申请锁,后一阶段只能释放锁。这样可以解决由于事务过早释放锁导致的问题,但仍然存留着一些问题,如死锁、读脏数据等。

严格两阶段封锁协议:排他锁必须在事务提交后释放。

强两阶段封锁协议:排他锁共享锁都需要在事务提交后才能释放。

下面简单回顾一下死锁。

死锁

  1. 概念:多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。
  2. 死锁定理:S为死锁状态的充分必要条件为S的资源分配图不可完全约简。
  3. 四个必要条件
    (1)资源互斥(2)不可剥夺(3)请求并保持(4)循环等待

小练习

事务T1和T2的操作按下列顺序到达系统:
R1(A) R2(B) W2(B) W1(A) R1(B) W2(A) W1(B)
试分析采用两阶段封锁协议时是否有死锁发生,并说明原因。

很明显是有的。当T1拿着A的X锁申请B的X锁,同时T2拿着B的X锁申请A的X锁的时候,死锁就发生了。

T1T2
XL(A)
R1(A)
XL(B)
R2(B)
W2(B)
W1(A)
XL(B)
XL(A)

基于日志的故障恢复策略

Redo和Undo

  1. 所有未完成的事务都需要Undo。因为根据原子性的特性,事务要么都做,要么都不做。所以只要没有做完就将其回滚。
  2. 所有已经完成的事务都需要Redo。因为尽管事务已经提交了,但我们不能保证事务已经从内存缓冲区写道磁盘上去,因此需要redo。

我们可以很容易地发现,Undo操作时不能省的。只要有事务没有做完,就必须要undo。而Redo是可以省的,因为有很多事务已经完成了并且写到磁盘上去,只不过我们并不知道哪些事务写到磁盘上去了而已。

于是采用检查点技术。

检查点

主要工作:
将当前所有位于缓冲区的日志、更新数据块写到磁盘上,然后创建日志记录,并将其写到磁盘上。L为当前活跃的事务。

当出现故障进行恢复的时候,分为三个阶段。

(1)分析阶段
从最后一个检查点开始顺向扫描日志,确定redo-set和undo-set。注意首先需要将L中的事务加入undo-set中。能进入redo-set的事务都时从undo-set中迁移过去的。

(2)撤销阶段
从日志反向扫描,进行撤销。

(3)重做阶段
从检查点顺向扫描,进行重做。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值