数据库管理 - 数据库系统原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库管理 - 数据库系统原理相关的知识,希望对你有一定的参考价值。

       在 DBS 运行时,DBMS 要对 DB 进行监控,以保证整个系统的正常运转,防止数据意外丢失和不一致数据的产生。DBMS 对 DB 的监控,称为 数据库管理

       主要通过四个方面实现:数据库的恢复、并发控制、完整性控制、安全性控制。每一方面构成了 DBMS 的一个子系统。

       DBS 运行的最小逻辑工作单位是“事务”,所有的数据库操作都要以事务作为一个整体单位来执行或撤销。

 

事务

       事务(Transaction) 是构成单一逻辑工作单元的操作集合,要么完整的执行,要么完全不执行。不论发生何种情况,DBS 必须保证事务能正确、完整地执行。

       DBS 执行事务,相当于操作系统环境中的“进程”概念,一个事务由 BEGIN TRANSACTION 语句开始,以 COMMIT 或 ROLLBACK 语句结束。

  • 事务的 ACID 性质(为保证数据库中数据总是正确的)
  1. 原子性(Atomic)。一个事务的所有操作是不可分割的单元,要么全部执行,要么什么也不做。由 DBMS 的事务管理子系统实现。
  2. 一致性(Consistency)。一个事务独立执行的结果,应保持数据库状态一致。由 DBMS 的完整性子系统实现。
  3. 隔离性(Isolation)。多个事务并发执行的结果,系统应保证与它们先后单独执行时的结果一样。由 DBMS 的并发控制子系统实现。
  4. 持久性(Durability)。一个事务完成全部操作后,对数据库的更新应永久的反映在数据库中,不会丢失。由 DBMS 的恢复管理子系统实现。

 

数据库的恢复

       系统能把数据库从被破坏、不正确的状态,恢复到最近一个正确的状态,DBMS 的这种能力称为 数据库的可恢复性。恢复的基本原则很简单,就是转储和建立日志数据库。当遭遇物理性灾难故障,可装入最近一次拷贝的数据库备份到新的磁盘,然后利用日志库执行“重做(REDO)”已提交的事务,可恢复到故障前。当遇到破坏了数据库的一致性时,不必拷贝存档,只要利用日志库“撤销(UNDO)”所有不可靠的修改。

  • 检查点方法

       大多数 DBMS 产品都提供这个方法来实现 REDO 和 UNDO。DBMS 定时设置检查点(Check point),在检查点时刻才真正把对 DB 的修改写到磁盘,同时在日志里写入一条检查点记录,以便恢复时使用。

p1-------p2---------p3--------

T1--->

T2--------->

T3---------------------->

       如果检查点 p3 为故障点,则 T1 不必恢复,因为执行结果已写入数据库;T2 需 REDO,虽然执行完,但对 DB 的修改尚在内存缓冲区,还未写到磁盘;T3 需 UNDO,因为还未做完。

 

数据库的并发控制

       并发操作可能会破坏数据库的完整性。这里的并发指在单 CPU 上用分时方法实行多个事务同时做,并发操作通常会带来三个问题丢失更新问题读脏数据问题不可重复读问题

  • 丢失更新问题

       例1. A = 100,T1 对 A 减 30,T2 对 A 加倍,若两个事务单独做,可见 A = 140 或 A = 170 都是正确的,看先后顺序。而当两个事务都读取了 A 值(100),T1 更新后 T2 再更新,则 A = 200,T1 的更新丢失了。

  • 读脏数据问题

       例2.(读脏数据但未破坏完整性) T1 把 A 改为 70,T2 读取 A 值 70,T1 执行了 ROLLBACK 操作,把 A 值 恢复为 100,而 T2 仍在使用被撤销了的 A 值 70。数据库中把未提交随后又撤销了的数据称为“脏数据”。

       例3.(读脏数据,引起自身更新被丢失,破坏了完整性)T1 把 A 改为 70,T2 读取 A 值 70,T2 执行了翻倍操作 A = 140 并更新,之后 T1 又执行了 ROLLBACK 操作,把 A 值从 70 又恢复为 100。这种情况更糟,T2 不仅读了未提交的 A 值(70),最后还丢失了子集的更新操作,破坏了数据库的完整性。

  • 不可重复读问题

       例4. T1 在一次事务中需要读取两次 A 值,但在这个时间间隔中 T2 改变了 A 的值,这就导致 T1 两次读取同一数据项 A 却出现不同的值。

 

封锁技术

       锁(Lock) 是一个与数据项相关的变量,对可能应用于该数据项上的操作而言,锁描述了该数据项的状态。为解决并发控制带来的问题,通常要采用封锁技术,常用的封锁有排他型封锁(X 锁)共享型封锁(S 锁)

  • 排他型封锁(简称 X 锁,最常用,又称为 写锁

       如果事务 T 对某个数据项 R 实现了 X 锁,那么在 T 对 R 解除封锁之前,不允许其他事务再对该数据加任何类型的锁,这种锁称为 X 锁

       使用 X 锁的操作有两个:

  1. 申请 X 锁操作“XFIND R”:事务对 R 申请加 X 锁,若成功,则可读写数据 R,如果不成功,那么这个事务将进入等待队列,一直到获准 X 锁,才能继续下去。
  2. 解除 X 锁操作“XRELEASE R”:表示事务要解除对数据 R 的 X 锁。为防止过早的解锁而造成其他事务读取了未提交的数据,系统中没有解除 X 锁操作的语句,而是合并在了 COMMIT 和 ROLLBACK 中。
  • 共享型封锁(简称 S 锁,又称为 读锁

       采用 X 锁的并发控制,并发度低,只允许一个事务独锁数据,而其他申请封锁的事务只能排队等待。为此,降低要求,允许并发的读,就引入了共享型封锁(Shared Lock)。允许多个事务都可对数据项 R 加 S 锁,但在该数据项上所有的 S 锁都解除之前决不允许任何事务对该数据加 X 锁

       使用 S 锁的操作有三个:

  1. 申请 S 锁操作“SFIND R”:事务对 R 申请加 S 锁,若成功,则可读数据 R,但不可以写数据 R;如果不成功,那么这个事务将进入等待队列,一直到获准 S 锁,才能继续下去。
  2. 升级和写操作“UPDX R”:事务要把对数据项 R 上的 S 锁升级为 X 锁,若成功则可更新数据 R,否则进入等待队列。
  3. 解除 S 锁操作“SRELEASE R”:解除对数据项 R 的 S 锁。由于 S 锁只允许读取数据,因此解除 S 锁不必非要合并到事务的结束操作中。

       S 锁可以解决丢失更新的问题,但带来了新的问题:死锁。如两个事务都申请了 S 锁,又都要升级为 X 锁去更新,谁也不解除,那就形成了死锁。

  • 封锁的粒度

       封锁的对象的大小称为 封锁的粒度封锁对象可以很大,如整个数据库;也可以很小,如某个属性值。封锁力度与系统的并发度和并发控制密切相关,封锁的粒度越大,并发度就越低,但同时系统的开销也就越小。

  • 封锁协议

       运用封锁机制时,要约定一些规则,称为协议。下表为三级封锁协议,在不同程度上解决了并发操作带来的问题,为正确调度提供一定的保证。

 

并发操作的调度

       事务的执行次序称为 事务的调度。如果多个事务依次执行,称为 事务的串行调度。如果利用分时的方法,同时处理多个事务,则称为 事务的并发调度

       如果有 n 个事务串行调度,则可能有 n! 种不同的有效调度。如果有 n 个事务并发调度,可能的并发调度数目远远大于 n!,但其中有的并发调度是正确的,有的是错误的。

  • 可串行化概念

       每个事务中,语句的先后顺序在各种调度中始终保持一致。在这个前提下,如果一个并发调度的执行结果与某一串行调度的执行结果等价,那么,这个并发调度称为 可串行化的调度,否则是不可串行化的调度。

       例如之前的例1,先 T1 后 T2 或者 先 T2 后 T1,A 的结果为 140 或 170,这两种串行调度都认为是正确的。而当 A 的执行结果为 200 时,与任何一个串行调度的结果都不相同,因而这种并发调度是错误的,即称为不可串行化的调度。

 

SQL 对并发处理的支持

       SQL2 对事务的存取模式(Access Mode)和隔离级别(Isolation Level)做了具体规定,并提供语句让用户使用,以控制事务的并发执行。

  • 事务的存取模式
  1. 只读型:定义这个模式后,随后的事务均为只读型。
  2. 读写型:定义这个模式后,随后的事务均为读写型。这是默认模式
SET     TRANSACTION     READ     ONLY
SET     TRANSACTION     READ     WRITE
  • 事务的隔离级别
  1. SERIALIZABLE(可串行化):默认级别。允许事务并发执行,但系统必须保证并发调度是可串行化的,不致发生错误。
  2. REPEATABLE READ(可重复读):只允许事务读已提交的数据,并且在两次读同一数据时不允许其他事务修改此数据。
  3. READ COMMITTED(读提交数据):允许事务读已提交的数据,但不要求“可重复读”。
  4. READ UNCOMMITTED(可以读未提交数据):允许事务读已提交或未提交的数据。SQL2 中允许的最低一致性级别
SET     TRANSACTION     ISOLATION     LEVEL     SERIALIZABLE
SET     TRANSACTION     ISOLATION     LEVEL     REPEATABLE     READ
SET     TRANSACTION     ISOLATION     LEVEL     READ     COMMITTED
SET     TRANSACTION     ISOLATION     LEVEL     READ     UNCOMMITTED

 

数据库的完整性

       数据库的完整性 是指数据的正确性、有效性、相容性,防止错误的数据进入数据库。所谓正确性指数据的合法性,如数值型不能放字母;有效性指数据是否属于定义的有效范围;相容性指表示同一事实的两个数据应相同。

  • DBMS 的完整性子系统功能:
  1. 监督事务的执行,并测试是否违反完整性规则。
  2. 若有违反现象,则采取适当的操作,如拒绝操作、报告违反情况、改正错误等方法来处理。
  • SQL 中的完整性约束,有下面三类:
  1. 域约束。 以 CREATE DOMAIN 语句定义新的域,可以以 CHECK 子句附加条件表达式。
  2. 基本表约束。 包括候选键定义、外键定义、检查约束定义。UNIQUE (<列名序列>) 实际上定义了候选键,但只表示唯一,值非空还需在列定义时有选项 NOT NULL。PRIMARY KEY (<列名序列>) 定义了表的主键,一个表只能有一个主键,且主键指定的列自动被认为是非空的。FOREIGN KEY (<列名序列>) REFERENCES <参照表> (<列名序列>) 定义了外键。CHECK (<条件表达式>) 是对单个关系中的元组值加以约束,如 CHECK AGE >= 15 AND AGE <= 30
  3. 断言。如果完整性约束与多个关系有关,或者涉及聚合操作,就可以使用断言机制书写。创建断言:CREATE ASSERTION <断言名> CHECK (<条件>);删除断言:DROP ASSERTION <断言名>。如 CREATE ASSERTION ass1 CHECK (10 >= SELECT COUNT(C#) FROM C GROUP BY T#) 表示教师授课不得超过 10 门课。

 

SQL 的触发器

       触发器(Trigger) 是一个能由系统自动执行对数据库修改的语句,由事件、条件和动作三部分组成。有时也称为主动规则或 事件 –> 条件 –> 动作规则(ECA 规则,Event Condition Action Rule)。

  1. 事件:指对数据库的增删改操作,这些事件发生时,触发器开始工作。
  2. 条件:触发器判断条件是否成立,如果成立,则执行相应的动作,否则什么也不做。
  3. 动作:DBMS 开始执行这些动作,如删除一些数据,插入一些元组,或一系列的数据库操作等。
-- 修改成绩时,修改后的成绩不能比原来低,否则就拒绝修改
CREATE     TRIGGER     TRIGGER1        
AFTER         UPDATE    OF    SCORE        ON         SC
REFERENCING
OLD     AS     OLDTUPLE
NEW     AS    NEWTUPLE
FOR    EACH        ROW
WHEN    (OLDTUPLE.SCORE > NEWTUPLE.SCORE)
        UPDATE SC SET SCORE = OLDTUPLE.SCORE WHERE C# = NEWTUPLE.C#

 

SQL 触发器的组成

  • 动作时间(定义了何时执行触发器的动作)
  1. BEFORE(SQL 标准):在触发事件进行前,先测试 WHEN 条件是否满足。若满足,则先执行触发器动作部分的操作,再执行触发事件的操作。
  2. AFTER(SQL 标准):在触发事件完成后,测试 WHEN 条件是否满足。若满足,则再执行触发器动作部分的操作。
  3. INSTEAD OF(Oracle 中):触发事件发生时,只要满足 WHEN 条件,就立刻执行动作部分的操作,而触发事件的操作不再执行。
  • 触发事件:UPDATE、DELETE、INSERT。只有 UPDATE 后可跟 OF <属性表> 短语指定某个属性,其他两种情况都是对整个元组的操作,不允许跟 OF <属性表> 短语。
  • 目标表:ON 短语
  • 旧值和新值的别名:如果触发事件是 UPDATE,则用“OLD AS”和“NEW AS”子句定义修改前后的元组变量;如果是 DELETE,只要用“OLD AS”;如果是 INSERT,只要用“NEW AS”
  • 触发动作:定义了当触发器被激活时想要它执行的 SQL 语句,有下面三个部分:
  1. 动作间隔尺寸:FOR EACH ROW(对每一个修改的元组都要检查一次,元组级触发器,行级触发器) 和 FOR EACH STATEMENT(对 SQL 语句的执行结果去检查,语句级触发器)。如果一条 SQL 语句需要修改 10 条记录,前者要运行 10 次,后者只运行 1次。
  2. 动作执行的条件:WHEN 子句,可以是任意表达式。
  3. 动作体:想要 DBMS 执行的 SQL 语句(仅当 WHEN 条件为 true 时)。

 

数据库的安全性

       数据库的安全性(Security) 是指保护数据库,防止不合法的使用,以免数据泄密、更改或破坏。安全性常与完整性混淆。安全性是保护数据以防止非法用户故意造成的破坏,完整性是保护数据以防止合法用户无意中造成的破坏。

  • 安全性级别
  1. 环境级:对计算机系统的机房和设备应加以保护,防止人为的物理破坏。
  2. 职员级:工作人员应清正廉洁,正确授予用户访问数据库的权限。
  3. OS 级:应防止未经授权的用户从 OS 处着手访问数据库。
  4. 网络级:大多数 DBS 都运行用户通过网络远程访问,因此,网络内部的安全很重要。
  5. DBS 级:检查用户的身份是否合法,以及使用数据库的权限是否正确。
  • 权限问题

       用户使用数据库的方式称为“权限”,有两种:访问数据修改数据库模式

  1. 访问数据的权限(4 个):读、增、删、改。
  2. 修改数据库结构(4 个):索引(增删)、资源(创建新的关系)、修改(在关系中增删属性)、撤销(撤销关系,DROP TABLE)。
  • SQL 中的安全机制
  1. 视图机制(View):用来对无权用户屏蔽数据,使用户只能使用视图定义中的数据,从而保证了数据库安全性。
  2. 权限机制(Authorization):保证用户只能进行其权限范围内的操作。
  3. 角色机制(Role):对具有不同权限的用户进行分组。
  4. 审计机制(Audit):建立用于安全性目的的数据库日志,以检查某一时间段内所有作用于数据库的存取动作和操作。
-- 权限表: SELECT    INSERT    UPDATE     DELETE    REFERENCES        USAGE
-- REFERENCES:允许用户定义新关系时,引用其他关系的主键作为外键
-- USAGE:允许用户使用已定义的域
-- WITH GRANT OPTION:表示获得权限的用户还能转授权限给其他用户
GRANT <权限表> ON <数据库元素> TO <用户名表> [WITH GRANT OPTION]
 
-- 例如
GRANT     SELECT     ON     S     TO     ZHANGSAN     WITH     GRANT     OPTION
GRANT     SELECT, UPDATE     ON     S     TO     WANG
 
-- 如要授予权限表中全部六种权限,可用 ALL PRIVILEGES
GRANT     ALL PRIVILEGES     ON     S     TO     WANG
 
 
-- 回收权限语句
-- CASCADE:表示连锁回收权限
-- RESTRICT:仅当没有连锁权限时才能回收该用户的权限
REVOKE <权限表> ON <数据库元素> FROM <用户名表> [ RESTRICT | CASCADE ]
  • 常用的安全性措施
  1. 强制存取控制:对每个数据对象和用户各自赋予一定的级别,用户能查看比它级别低或同级的数据,但只能修改和它同级的数据。(这种方法只在专用数据库中有用)
  2. 统计数据库的安全性:在“统计数据库”中,通过对用户查询得到的记录数加以控制和“数据污染”两种方法来保证数据库的安全性。
  3. 自然环境的安全性:即 DBS 的设备和硬件的安全性。

以上是关于数据库管理 - 数据库系统原理的主要内容,如果未能解决你的问题,请参考以下文章

YASnippet - emacs 的代码片段管理工具

数据库系统原理课程设计 -----图书借阅管理系统

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 32bit 系统)

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 32bit 系统)

数据库原理—数据库管理系统的功能和特点

数据库原理-数据库管理系统层次与结构