数据库设计与数据库恢复对应数据库原理内容的第六章和第七章。
ch6.数据库设计
6.1 需求分析
数据字典是各类数据描述的集合,是进行详细的数据收集和数据分析所获得的主要结果。数据字典在数据库设计中占有很重要的地位,其主要内容包括:
- 数据项:是不可再分的数据单位。数据项描述={数据项名,数据项含义说明,别名,数据类型,长度,取值范围,取值含义,与其他数据项的逻辑关系}
- 数据结构:反映了数据之间的组合关系。一个数据结构可以由若干数据项或数据结构组成。数据结构描述={数据结构名,含义说明,组成:{数据项或数据结构}}
- 数据流:是数据结构在系统内传输的路径。数据流描述={数据流名,说明,数据流来源,数据流去向,组成:{数据结构}, 平均流量,高峰期流量}
- 数据存储:是数据结构的停留或保存处,也是数据流的来源和去向之一。数据存储描述={数据存储名,说明,编号,流入的数据流 ,流出的数据流,组成:{数据结构},数据量,存取方式}
- 处理过程:具体处理逻辑一般用判定表或判定树来描述,数据字典中只需要描述处理过程的说明性信息。处理过程描述={处理过程名,说明,输入:{数据流},输出:{数据流},处理:{简要说明}}
【例】学生学籍管理子系统的数据字典。
数据项以学号为例:
数据项: 学号
含义说明:唯一标识每个学生
别名: 学生编号
类型: 字符型
长度: 8
取值范围:00000000至99999999
取值含义:前两位标别该学生所在年级,后六位按顺序编号
数据结构以学生为例:
数据结构: 学生
含义说明: 定义了一个学生的有关信息
组成: 学号,姓名,性别,年龄,所在系,年级
数据流以体检结果为例:
数据流: 体检结果
说明: 学生参加体格检查的最终结果
数据流来源:体检
数据流去向:批准
组成: ……
平均流量: ……
高峰期流量:……
数据存储以学生登记表为例:
数据存储: 学生登记表
说明: 记录学生的基本情况
流入数据流:…… 流出数据流:……
组成: ……
数据量: 每年3000张 存取方式: 随机存取
处理过程以分配宿舍为例:
处理过程:分配宿舍
说明: 为所有新生分配学生宿舍
输入: 学生,宿舍,
输出: 宿舍安排
处理: 在新生报到后,为所有新生分配学生宿舍。要求同一间宿舍只能安排同一性别的学生,同一个学生只能安排在一个宿舍中。每 个学生的居住面积不小于3平方米。安排新生宿舍其处理时间应不超过15分钟。
6.2 概念结构设计
描述概念模型的工具是E-R模型。
6.2.1 设计概念结构的四类方法
- 自顶向下:先定义全局概念结构的框架,再逐步细化。
- 自底向上:先定义各局部应用的概念结构,再将它们集成起来,得到全局概念结构。
- 逐步扩张:先定义最重要的核心概念结构,再向外扩充,以滚雪球的方式逐步生成其他概念结构,直至总体概念结构。
[“滚雪球”的方式]
- 混合策略:将自顶向下和自底向上相结合,用自顶向下策略设计一个全局概念结构的框架,以它为骨架集成由自底向上策略中设计的各局部概念结构。
常用策略有:自顶向下地进行需求分析、自底向上地设计概念结构。自底向上设计概念结构的步骤是先抽象数据并设计局部视图,再集成局部视图,得到全局概念结构。
6.2.2 数据抽象
数据抽象:概念结构是对现实世界的一种抽象。所谓抽象是从实际的人、物、事和概念中抽取所关心的共同特性,忽略非本质的细节,并把这些特性用各种概念精确地加以描述,这些概念组成了某种模型。一般有三种常用抽象:
- 分类(Classification):定义某一类概念作为现实世界中一组对象的类型。这些对象具有某些共同的特性和行为,它抽象了对象值和型之间的“is member of”的语义,如张三是学生中的一员。即:客观世界同一类的对象用一种数据类型来表示。在E-R模型中,实体型就是这种抽象。联系也属于一种对象。
- 聚集(Aggregation):定义某一类型的组成成分。它抽象了对象内部类型和成分之间“is part of”的语义。在E-R模型中若干属性的聚集组成了实体型,就是这种抽象。如学号、姓名、专业、等属性的聚集组成学生实体型。
- 概括(Generalization):定义类型之间的一种子集联系。它抽象了类型之间的“is subset of”的语义。如学生是实体型,本科生、研究生也是实体型,本科生、研究生是学生的子集,称学生为超类,本科生、研究生为子类。概括具有继承性:子类继承超类上定义的所有抽象。 E-R模型中用双竖边的矩形框表示子类,用直线加小圆圈表示超类-子类的联系。
实体和属性的区分:实体与属性是相对而言的,同一事物在一种应用环境中作为属性,在另一应用环境中就必须作为实体。
确定为属性的两条准则是:
-
属性必须是不可分的数据项;
-
属性不能与其他实体具有联系,联系只发生在实体之间。
如职工是一个实体,职工号、姓名、年龄是职工的属性,职称如果没有与工资、福利挂钩,即没有需要进一步描述的特性,则根据准则1可以作为职工实体的属性。但如果不同的职称有不同的工资、住房标准和不同的附加福利,则职称将作为一个实体看待。
一个实体转化成一个表,它的属性就是表的属性;联系可以转化成一个独立的关系/表。
【例】第二个E-R图可以转化成三个表,职工、职称、聘任(职工号、职称代码)。
6.2.3 视图集成
视图集成的两种方式:
- 一次集成:一次集成多个分E-R图,适用于局部视图较简单时
- 逐步累积:首先集成两个局部视图(通常是比较关键的两个局部视图),以后每次将一个新的局部视图集成进来。
无论哪种方式,集成局部E-R图必须经过两步:合并分E-R图,生成初步E-R图。
由于各个局部应用所面向的问题不同,且由不同的设计人员进行设计,这就导致了各个分E-R图之间必定存在冲突。合并分E-R图的主要工作与关键所在就是合理消除各分E-R图的冲突。
冲突主要分为如下三类:
- 属性冲突
- 属性域冲突:即属性值的类型、取值范围或取值集合不同。如零件号,有的部门将它定义为整型,有的部门将它定义为字符型。又如年龄,有些部门以出生日期形式表示职工年龄,而另一些部门用整数形式表示职工年龄。
- 属性取值单位冲突:如零件的重量,有的以公斤为单位,有的以斤为单位,有的以克为单位。
属性冲突通常用讨论、协商等手段加以解决。
- 命名冲突:可能发生在属性级、实体级、联系级上。命名冲突通常用讨论、协商等手段解决。
- 同名异义:不同意义的对象在不同局部应用中具有相同名字。
- 异名同义:同一意义的对象在不同局部应用中具有不同名字。如对科研项目,财务科称为项目,科研处称为课题。
6.3 逻辑结构设计
下面介绍E-R图向关系模式的转换。
(1)一个实体型转换为一个关系模式:**实体的属性就是关系的属性,实体的码就是关系的码。**如职工实体可以转换为关系模式职工(职工号,姓名,年龄,职称)
(2)实体间的联系转换有以下不同情况:
-
一个1:1联系可以转换为:
-
一个独立的关系模式:关系模式的名字就是联系的名字,相联系两端实体的码以及联系本身的属性都是关系模式的属性,任意一端实体的码都是它的码(存在两个候选码)。
如下面的E-R图中,负责(职工号,产品号),职工(职工号,……,产品号),产品(产品号,……)。[多了一个表]
职工号、产品号均可作为关系模式的码。
-
与任意一端实体合并:加入另一端实体的码以及联系的属性,码不变。
如下面的E-R图中,职工(职工号,……,产品号),产品(产品号,……)
-
-
一个1:n联系可以转换为:
-
一个独立的关系模式:n端的码是新的关系模式的码,其余与1:1联系相同。
如下面的E-R图中,
部门(部门号,……),职工(职工号,姓名,……)
属于(部门号,职工号[码])
-
1端与n端合并:要加到n端,码不变。
如下面的E-R图中,职工(职工号,……,部门号)
-
-
一个m:n联系只能转换为一个独立的关系模式,码是两端实体码的组合。
如下面的E-R图中,零件-仓库联系中,库存(零件号,仓库号[码],库存量[联系本身的属性])。
ch7.数据库恢复与并发控制
7.1 事务
事务(transaction):用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。
其中,Begin Transction表示事务的开始, Commit为事务提交,即告诉事务管理器事务中的所有操作都已完成,数据库处于另一个一致性状态;而RollBack为事务回滚,即告诉事务管理器事务执行时发生故障,所有已完成的操作必须全部撤销,滚回到事务开始的状态。这里的操作指对数据库的更新操作。
事务的性质:事务具有ACID特性。
- 原子性(Atomicity):事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做;
- 一致性(Consistency):事务的执行必须保证数据库从一个一致性状态转到另一个一致性状态,并行调度与串行调度结果一致(若不一致,把此现象称为”丢失修改”)。为了保证其不冲突,需要采用协议,在这里采用封锁的方法——X锁(对数据进行修改)、S锁(读锁,Shared Lock),上锁后其他人不能修改;
- 隔离性(Isolation):一个事务的执行不能被其他事务干扰,并发执行的各个事务间应互相独立;
- 持久性(Durability):事务一旦提交,它对数据库中数据的改变应是永久的。
[例] T1事务表示A转帐100元到B, T2事务表示从A中取100元。
- 一致性:T1单独执行时A+B应不变,如果只write(A)没有write(B),就不一致;T1、T2并发执行时,A应去掉200元,否则不一致;
- 原子性:T1必须全部执行6个操作;
- 隔离性:T1、T2相互独立,不应产生数据错误;
- 持久性:T1执行后,对数据库的修改永久存在。
保证事务ACID特性是事务处理的任务。事务ACID特性可能遭到破坏的因素有:
- 多个事务并行运行时,不同事务的操作交叉执行
- 事务在运行过程中被强行停止
7.2 故障的种类
恢复子系统是DBMS的一个重要组成部分,保证故障发生后能把数据库中的数据从错误状态恢复到某一已知的正确状态,保证事务ACID。恢复技术是衡量系统优劣的重要指标。一般一个大型数据库产品,恢复子系统的代码要占全部代码的10%以上。 下面介绍故障的种类。
1.事务故障:
某个事务在运行过程中由于种种原因未运行至正常结束点就夭折了,造成数据库可能处于不正确状态。
事务故障的原因:违反了某些完整性限制、输入数据有误、运算溢出、并行事务发生死锁等。
恢复子系统一般采用回滚(RollBack),强行撤销(UNDO)该事务对数据库的所有修改,使得这个事务象根本没有启动过一样。
2.系统故障:
系统故障(软故障)指造成系统停止运转的任何事件,使得系统要重新启动。这类故障影响所有正在运行的事务,但不破坏整个数据库。这时内存数据丢失,所有运行事务都异常终止。
系统故障的原因:特定类型的硬件错误(如CPU故障)、操作系统故障、DBMS代码错误、突然停电等。
系统故障的恢复:
-
日志文件数据不完整,将已经做的全部撤销
发生系统故障时,一些尚未完成的事务可能已将部分更新操作写回数据库,使数据库处于不正确状态,所以恢复子系统在系统重启时必须让所有非正常终止的事务回滚,强行撤销(UNDO)所有未完成事务。
-
日志文件数据完整(知道操作),数据文件数据不完整----->根据日志继续操作
发生系统故障时,有些已完成事务可能部分甚至全部留在缓冲区,尚未写回磁盘,系统故障使得这些事务对数据库的修改部分或全部丢失,数据库处于不一致状态,因此恢复子系统在系统重启时,还必须**重做(**REDO)所有已提交事务。
3.介质故障:
介质故障(硬故障)使存储在外存中的数据部分丢失或全部丢失。介质故障发生的可能性较小,但破坏性大,破坏数据库或部分数据库,并影响正在存取这部分数据的所有事务。
介质故障的原因:磁盘损坏、磁头碰撞、瞬时强磁场干扰等。
介质故障的恢复:装入介质故障前某个时刻的数据副本,重做自此时开始的所有成功事务,将这些事务已提交的结果重新记入数据库。
7.3 恢复的实现技术
恢复机制涉及的两个关键问题:如何建立冗余数据(数据转储backup、登录日志文件logging)、 如何利用这些冗余数据实施数据库恢复。
数据转储:指DBA将整个数据库复制到磁带或另一磁盘上保存起来的过程。这些备用的数据文本称为后备副本或后援副本。
数据转储分为两类:
-
静态转储:系统中无运行事务时进行转储,即转储开始时数据库处于一致性状态,而转储期间不允许对数据库的任何存取、修改操作。优点是实现简单;缺点是转储必须等用户事务结束,新的事务必须等转储结束,降低了数据库的可用性。
-
动态转储:转储期间允许对数据库进行存取或修改,即转储操作与用户事务可以并发进行。优点是不用等待正在运行的用户事务结束,不会影响新事务的运行;缺点是不能保证副本中的数据正确有效,如转储期间的某个时刻Tc系统将数据A=100转储,而在下一时刻Td某一事务将A改为200,转储结束后,后备副本上A的值已经过时。因此,必须利用日志文件进行恢复。
数据转储还可以分为以下两类:(均可以动态/静态)
- 海量转储:转储全部数据。
- 增量转储:每次只转储自上一次转储后更新过的数据。
从恢复角度看,使用海量转储得到的后备副本进行恢复往往更方便。但如果数据库很大,事务处理又十分频繁,则增量转储方式更实用更有效。
7.4 日志
日志文件的内容:每个事务的开始标记(BEGIN TRANSACTION)、结束标记(COMMIT或ROLLBACK)和每个更新操作均可作为日志文件中的一个日志记录 (log record)。
基于记录的日志文件:每条日志记录的内容有事务标识、操作类型(插入、删除或修改)、操作对象(记录ID)、更新前数据的旧值(插入操作此项为空)、更新后数据的新值(删除操作此项为空)
基于数据块的日志文件:每条日志记录的内容有事务标识、被更新的数据块Block NO.、更新前数据所在数据块的值(插入操作此项为空)、更新后数据所在数据块的值(删除操作此项为空)
日志文件示例:
日志的操作必须遵循以下两点原则:
- 登记的次序严格按照并行事务执行的时间次序。
- 必须先写日志文件,后写数据库写日志文件操作(“先期写入”协议)
把对数据的修改写到数据库中和把表示这个修改的日志记录写到日志文件中是两个不同的操作。有可能在这两个操作之间发生故障,即两个写操作只完成了一个。若先写了数据库修改,而在日志文件中没有登记这个修改,我们无法知道数据库是否修改,则以后就无法恢复这个修改了;若先写日志,但没有修改数据库,按日志文件恢复时只不过是多执行一次不必要的UNDO操作,并不会影响数据库的正确性。
7.5 恢复策略
7.5.1 事务故障的恢复
事务故障指事务在运行至正常终止点前被中止,这时恢复子系统应利用日志文件撤消(UNDO)此事务已对数据库进行的修改。事务故障的恢复由系统自动完成,对用户是透明的。恢复步骤是:
- 反向扫描文件日志(即从最后向前扫描日志文件),查找该事务的更新操作。
- 对该事务的更新操作执行逆操作。即若记录中是插入操作, “更新前的值”为空,则相当于做删除操作;若记录中是删除操作,“更新后的值”为空,则相当于做插入操作;若记录中是修改操作,则用修改前值代替修改后值。
- 继续反向扫描日志文件,查找该事务的其他更新操作,并做同样处理。
- 如此处理下去,直至读到此事务的开始标记,事务故障恢复就完成了。
7.5.2 系统故障的恢复
系统故障造成数据库不一致状态的原因有两个,一是未完成事务对数据库的更新已写入数据库,二是一些已提交事务对数据库的更新还留在缓冲区没来得及写入数据库。因此恢复操作要UNDO故障发生时未完成的事务,REDO已完成的事务。系统故障的恢复由系统在重新启动时自动完成,不需要用户干预。恢复步骤是:
- 正向扫描日志文件(即从头[老时间—>新时间]扫描日志文件),找出在故障发生前已经提交的事务(这些事务既有Begin Transaction记录,又有Commit记录),将其事务标识放入REDO队列(继续做完);同时找出故障发生时尚未完成的事务(这些事务只有Begin Transaction记录、但无Commit记录),将其事务标识放入UNDO队列(全部撤销)。
- 反向扫描日志文件,对UNDO队列中各个事务进行撤销处理。
- 正向扫描日志文件,对REDO队列中各个事务进行重做处理。
[注意]必须先UNDO再REDO。
[例]设事务T1在A中存100,执行更新后在提交之前被中止。事务T2在A中存200,并提交。
T1没有结束标志,T2有开始、结束的标志。
介质故障的恢复与系统故障的恢复相同,发生介质故障后,磁盘上的物理数据和日志文件被破坏,这是最严重的一种故障。恢复方法是重装数据,然后重做已完成的事务。
7.6 并发控制
7.6.1 并发操作引起的问题
并发操作可能引起的三类数据不一致问题:
丢失修改:指两个事务T1和T2从数据库中读入同一数据并修改,T2的提交结果破坏了T1提交的结果,导致T1的修改被丢失
不可重复读:不可重复读是指事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取结果。
不可重复读包括三种情况:
- 事务T1读取某一数据后,事务T2对其做了修改,当T1再次读该数据时,得到与前一次不同的值。
- 事务T1按一定条件从数据库中读取了某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录神秘地消失了。
- 事务T1按一定条件从数据库中读取了某些数据记录后,事务T2插入了一些记录,当T1再次按相同条件读取数据时,发现多了一些记录。
后两种情况也称为幻影现象(Phantom Row)。
读“脏”数据:事务T1修改某一数据,并将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被撤消,这时事务1已修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致,则T2读到的数据称为“脏”数据。(读了数据库中没有的数据)
7.6.2 封锁
任何事务T在对某数据操作之前,先向系统发出请求对其加锁。加锁后事务T就对该数据拥有了一定的控制权,在事务T释放锁之前其它事务不能更新该数据。
- 排它锁(X锁,写锁):若事务T对数据A加X锁,则只允许T读取和修改A,其他事务不能再对A加任何锁,直到T释放A上的X锁。它保证了在T释放A上X锁之前其他事务不能再读取和修改A ;
- 共享锁(S锁,读锁):若事务T对数据A加S锁,则事务T只可读A,但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。它保证了在T释放A上S锁之前其它事务可以读A,但不能修改A。
X锁和S锁的相容性:Y为相容,N为不相容。若两个锁不相容,则后提出锁请求的事务必须等待。
7.6.3 封锁协议
封锁协议是指事务对数据封锁时,何时申请X锁或S锁、持锁时间、何时释放等有关封锁的规则。
- 一级封锁协议:事务T在修改数据A之前必须先对其加X锁,直到该事务结束才释放X锁 (防丢失修改);
- 二级封锁协议:一级封锁协议加上事务T在读取数据A前必须先对其加S锁,读完后立即释放S锁(防丢失修改,防读“脏”数据);
- 三级封锁协议:一级封锁协议加上事务T在读取数据A前必须先对其加S锁,直到该事务结束才释放S锁(防丢失修改,防读“脏”数据,防不可重复读)。