数据库的数据保护主要包括数据的安全性和完整性。
数据库的安全性是指保护数据库以防不合法使用所造成的数据泄露,更改或破坏。
安全性:去银行取钱需要输入密码
完整性:取的钱需要小于等于卡里面的钱
存取控制(AC–Acess Control)
基于角色访问控制(RBAC—Role-Based Acess Control)
数据库的安全性,主要包括身份鉴定、多层存取控制、审计、视图和数据加密等安全技术。
存取控制流程:
用户身份鉴别是数据库管理系统提供的最外层安全保护措施。
每个用户在系统中都有一个用户标识。
每个用户标识都由 用户名(user name) 和**用户标识号(UID) **两部分组成。
静态口令鉴别
动态口令鉴别
智能卡鉴别
用户权限是由两个要素组成:数据库对象和操作类型。(用户可以在数据库的哪些对象上进行哪些操作)在数据库系统中,定义存取权限称为授权。
在关系数据库系统中,存取控制对象不仅有数据本身(基本表中的数据,属性列上的数据),还有数据库模式(包括数据库、基本表、视图和索引的创建等)。
SQL中使用==GRANT(授予)和REVOKE(收回)==语句向用户授予或收回数据的操作权限。
GRANT语法格式:
GRANT<权限>[,<权限>]...
ON <对象类型><对象名>[,<对象类型><对象名>]...
TO <用户>[,<用户>]...
[WITH GRANT OPTION]
如果添加了WITH GRANT OPTION子句,则获得某种权限的用户还可以把这种权限再授予给其他用户,但是不允许循环授权,即被授予者不能再把权限授予给授权者或祖先。
#把查询Student表的权限授予给用户U1
GRANT SELECT
ON TABLE Student
TO U1;
#把对Student和Course表的全部权限授予给用户U2和U3
GRANT ALL PRIVILEGES
ON TABLE Student,Course
TO U2,U3;
#把对SC表的查询权限给所有用户
GRANT SELECT
ON TABLE SC
TO PUBLIC;
#把查询Student表和修改学生学号的权限给U1
#注意:对属性列授权时必须明确指出相应的属性列名
GRANT SELECT,UPDATE(Sno)
ON TABLE Studnet
TO U1;
REVOKE语法格式:
REVOKE <权限>[,<权限>]...
ON <对象类型><对象名>[,<对象类型><对象名>]...
FROM <用户>[,<用户>]...[CASCADE|RESTRICT];
#把用户U4修改学生学号的权限收回
REVOKE UPDATE(Sno)
ON TABEL Student
FROM U4;
#假设U5还将INSERT权限授予给了U6用户,现在把用户U5对SC表的INSERT权限收回
REVOKE INSERT
ON TABLE SC
FROM U5 CASCADE;
#注意:这里使用的是CASCADE,有的数据库管理系统默认为RESTRICT,将自动执行级联删除。
创建数据库模式的权限
CREAT USER <username>[WITH][DBA|RESOURCE|CONNECT];
数据库角色是被命名的一组与数据库操作有关的权限,角色是权限的集合。 使用角色来管理数据库权限可以简化授权的过程。
在SQL中首先用CREAT ROLE 语句创建角色,然后用GRANT语句角色授权,用REVOKE语句回收授予角色的权限。
1.角色的创建
CREAT ROLE <角色名>
2.给角色授权
GRANT <权限>[,<权限>]...
ON <对象类型> 对象名
TO <角色>[,<角色>]...
3.将一个角色授予给其他的角色或用户
GRANT <角色1>[,<角色2>]...
TO <角色3>[,<用户1>]...
[WITH ADMIN OPTION]
4.角色的回收
REVOKE <权限>[,<权限>]...
ON <对象类型><对象名>
FROM <角色>[,<角色>]...
CREAT ROLE R1;
GRANT SELECT,UPDATE,INSERT
ON RABLE Student
TO R1;
GRANT R1
TO 王平,张明,赵玲;
REVOKE R1
FROM 王平;
强制存取控制是指系统为保证更高程度的安全性,按照TDI/TCSEC标准中安全策略的要求采取的强制存取检查手段。
在强制存取控制中,数据库管理系统所管理的全部实体被分为主体和客体两大类。
对于实体和客体,系统为他们每个实例指派一个敏感度被标记。敏感度标记分为若干级,绝密、机密、可信、公开等。
要求:
那为什么高级别的主体(用户)不能写低级别的客体(文件)?
#建立计算机系学生的视图,把对该视图的SELECT权限授予王平,把该视图上的所有操作权限授予张明
CREAT VIEW CS_Student
AS
SELECT * FROM Student
WHERE Sdept='CS';
GRANT SELECT
ON CS_Student
TO 王平;
GRANT ALL PRIVILEGES
ON CS_Student
TO 张明;
审计功能把用户对数据库的所有操作自动记录下来放进审计日记中。
审计员可以利用审计日记监控数据库中的各种行为,重现导致数据库现有现状的一系列事件,找出非法存取数据的人、事件和内容等,还可以进行防范。
AUDIT语句和NOAUDIT语句
AUDIT语句用来设置审计功能,NOAUDIT用来取消审计功能。审计又可分为用户级审计和系统级审计。
#对修改SC表结构或修改SC表数据的操作进行审计
AUDIT ALTER,UPDATE
ON SC;
#取消对SC表的一切审计
NOAUDIT ALTER,UPDATE
ON SC;
数据加密主要包括存储加密和传输加密:
存储加密
传输加密
数据库的完整性是指数据的正确性和相容性。
#将Student表中的Sno属性定义为码
CREATE TABLE Student(
Sno char(9) PRIMARY KEY, #在列级定义主码
Sname char(20) NOT NULL,
Ssex char(2),
Sage SMALLINT,
Sdept CHAR(20)
);
#或
CREATE TABLE Student(
Sno char(9), #在列级定义主码
Sname char(20) NOT NULL,
Ssex char(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY(Sno) #在表级定义主码
);
#注意:对多个属性构成的主码,只能定义为表级约束条件
(1)检查主码的值是否唯一,如果不唯一则拒绝插入或修改
(2)检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改
一般检查如果通过全表扫描十分耗时。一般通过在主码上自动建立一个索引来提高效率。
#定义SC中的参照完整性
CREATE TABLE SC(
Sno CHAR(9) NOT NULL,
Cno CHAR(9)NOT NULL,
Grade SMALLINT,
PRIMARY KEY(Sno,Cno), #在表级上定义实体完整性
FOREIGN KEY(Sno) REFERNECES Student(Sno), #在表级上定义参照完整性
FOREIGN KEY(Cno) REFERNECES Student(Cno) #在表级上定义参照完整性
);
当发生上述操作,可以采取:
CREATE TABLE SC(
Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT,
PRIMARY KEY(Sno,Cno), #在表级定义实体完整性 Sno和Cno都不能为空值
FOREIGN KEY(Sno) REFERENCE Student(Sno) #在表级定义参照完整性
ON DELETE CASCADE #当删除Student表中的元组时,级联删除SC表中对应的元组
ON UPDATE CASCADE #当更新Student表中的Sno时,级联更新SC表中相应的元组
FOREIGN KEY(Cno) REFERENCE Course(Cno) #在表级定义参照完整性
ON DELETE NO ACTION #当删除Course表中的元组造成与SC表不一致时,拒绝删除
ON UPDATE CASCADE #当更新Course表中的Cno时,级联更新SC表中相应的元组
);
前面已经有了元组约束条件,为什么还要有完整性约束子句?
1.属性上的约束条件定义
CREATE TABLE Student(
Sno CHAR(9) PRIMARY KEY, #在列级定义主码
Sname CHAR(8) NOT NULL, #Sname属性不为空
Ssex CHAR(2) CHECK(Ssex IN('男','女')), #性别属性Ssex只允许取男或女
Sage SMALLINT,
Sdept CHAR(20)
);
2.属性上约束条件的检查和违约处理
当往表中插入元组或修改属性的值时,关系数据库管理系统将检查属性上的约束条件是否满足,如果不满足则操作被拒绝执行
CONSTRAINT <完整性约束条件名><完整性约束条件>
CREATE TABLE Student(
Sno NUMERIC(6)
CONSTRAINT C1 CHECK(Sno BETWEEN 90000 AND 99999),
Sname CHAR(20)
CONSTRAINT C2 NOT NULL,
Sage NUMERIC(3)
CONSISTENT C3 CHECK(Sage<30),
Ssex CHAR(2)
CONSTRAINT C4 CHECK(Ssex IN('男','女')),
CONSTRAINT StudentKey PRIMARY KEY(Sno),
);
2.修改表中的完整性限制
使用ALTER TABLE 语句修改表中的完整性限制
ALTER TABLE Student
DROP CONSTRAINT C4;
ALTER TABLE Student
DROP CONSTRAINT C1;
ALTER TABLE Student
ADD CONSTRAINT C1 CHECK(Sno BETWEEN 900000 AND 999999);
#建立一个性别域,并声明性别域的取值范围
CREATE DOMAIN GenderDomain CHAR(2)
CHECK(VALUE IN('男','女'));
#这样,对sex的说明改写为:
Ssex GenderDomain;
#建立性别域,并对其中的限制命名
CREATE DOMAIN GenderDomain CHAR(2)
CONSTRAIN GD CHECK(VALUE IN('男','女'));
#删除GenderDomain的限制条件GD
ALTER DOMAIN Genderdomain
DROP CONSTRAIN GD;
#删除原来的限制条件并在性别域增加限制条件GDD
ALTER DOMAIN GenderDomain
DROP CONSTRAIN GD;
ALTER DOMAIN GenderDomain
ADD CONSTRAIN GDD CHECK('1','0');
#限制每一门课程最多60名学生选修
CREATE ASSERTION ASS_SC_CNUM1
CHECK(60>=(
SELECT COUNT(*) FROM SC GROUP BY Cno
));
触发器是由用户定义在关系表上的一类由事件驱动的特殊过程。
触发器的优点
触发器的缺点
#当触发事件发生时,该触发器被激活
CREATE TRIGGER<触发器名>
{BEFORE|AFTER}<触发事件>ON <表名>
REFERENCING NEW|OLD ROW AS<变量> #REFERENCING指出引用的变量
FOR EACH {ROW|STATEMENT} #定义触发器的类型,指明动作执行的频率
[WHEN<触发条件>]<触发动作体> #仅当触发条件为真时才执行触发动作体
#定义一个BEFORE行级触发器,为教师表Teacher定义完整性规则“教师的工资不低于4000元,如果低于4000,则改为4000”
CREATE TRIGGER Insert_Or_Update_Sal
BEFORE INSERT OR UPDATE ON Teacher #触发事件是插入或更新
FOR EACH ROW #行级触发器
BEGIN #定义触发动作体,是PL/SQL过程块
IF(new.job='教授') AND (new.Sal<4000)
THEN new.Sal:=4000
END IF;
END;
#定义AFTER行级触发器,当教师表Teacher的工资发生变化后自动工资表Sal_log中增加一条相应的记录
#首先建立工资变化表Sal_log
CREATE TRIGGER Sal_log
(
Eno NUMERIC(4) references teacher(eno),
Sal NUMERIC(7,2),
Username VARCHAR(10),
Date TIMESTAMP
);
CREATE TRIGGER Insert_Sal
AFTER INSERT ON Teacher #触发事件是INSERT
FOR EACH ROW
BEGIN
INSERT INTO Sal_log
VALUES(
new.Eno,new.Sal,CURRENT_USER,CURRENT_TIMESTAMP
);
END;
多个触发器,遵循如下的执行顺序:
触发器优先级:
#删除教师表Teacher上的触发器
DROP TRIGGER Insert_Sal ON Teacher;
针对一个具体问题,应该如何构建一个适合他的数据库模式,即应该构造几个关系模式,每个关系模式由哪些属性组成等——数据库逻辑设计问题——关系数据库规范化理论
关系数据库的规范化理论主要包括三个方面的内容:
一个好的关系模式应该具备以下四个条件:
数据依赖:关系模式中的各属性之间的相互依赖、相互制约的联系称为数据依赖。数据依赖一般分为函数依赖、多值依赖和连接依赖。
平凡函数依赖与非平凡函数依赖:
传递函数依赖:设有关系模式R(U),U是属性全集,X,Y,Z是U的子集,若X->Y,但Y-/->X而Y->Z,则称Z对X传递函数依赖:X-t->Z。如果Y->X,那么称Z对X直接函数依赖,而不是传递函数依赖。
函数依赖分为:
范式(数据库关系设计达到要求的具体程度)
是最基本的规范模式,即关系中的每个属性都是不可再分的简单项,即不存在表中有表的情况.
如果关系模式R所有的属性均为简单属性,即每个属性都是不可再分的,则称R属于第一范式,简称1NF,记作R∈1NF。
然而,一个关系模式仅属于第一范式是不适用的,比如SCD(SNO,CNO,Score,SN,Dept,MN,Age),有大量的数据冗余,插入异常,删除异常和更新异常等弊端。在SCD中,既存在完全函数依赖,也存在部分函数依赖,显然情况在数据库中是不允许的。克服这些弊端的方法是进行关系分解,去掉过于复杂的函数依赖关系,向更高一级的范式进行转换。
第一范式的目标是:将基本数据划分成称为实体集或表的逻辑单元,当设计好每个实体后,需要为其指定主码.
如果关系模式R∈1NF,且每个非主属性都完全函数依赖于R的主关系键,则称R属于第二范式,简称2NF,记住R∈2NF。
2NF的缺点:
第二范式的目标:将只部分依赖于候选码(即依赖于候选码的部分属性)的非主属性移到其他表中。
S-L-C这个函数依赖图中非主属性Sdept和Sloc部分函数依赖于码(Sno, Cno)
如果关系模式R∈2NF,且每个非主属性都不传递函数依赖于R的主关系键
通常认为BCNF是修正的第三范式,有时也称为扩充的第三范式。
一个满足BCNF的关系模式有:
BCNF范式排除了:
关系模式STJ(S,T,J)中,S表示学生,T表示教师,J表示课程。每一教师只教一门课,
每门课有若干教师,某一学生选定某门课,就对应一个固定的教师。
由语义可得到函数依赖:(S,J)→T;(S,T)→J;T→J
因为没有任何非主属性对码传递依赖或部分依赖,
STJ ∈ 3NF。
因为T是决定因素,而T不包含码,所以STJ 不属于 BCNF 关系。
设计概念结构通常有四类方法
自顶向下:即首先定义全局概念结构的框架,然后逐步细化
自底向上:即首先定义各局部应用的概念结构,然后将它们集成起来,得到全局概念结构
逐步扩张:首先定义最重要的核心概念结构,然后向外扩充
混合策略:即将自顶向下和自底向上相结合,用自顶向下策略设计一个全局概念结构的框架,以它为骨架集成由自底向上策略中设计的各局部概念结构。
E-R图如何转换为关系模型?
(1)一个1:1联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并。如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,每个实体的码均是该关系的码;如果与某一端实体对应的关系模式合并,则需要在该关系模式的属性中加入另一个关系模式的码和联系本身的属性。(联系本身的属性?)
(2)一个1:n联系可以转换为一个独立的关系模式,也可以与n端对应的关系模式合并。如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为n端实体的码
(3)一个m:n联系转换为一个关系模式。与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,各实体的码组成关系的码或关系码的一部分
尽管数据库系统中采取了各种保护措施来防止数据库的安全性和完整性被破坏以及并发事务的正确执行,但某些故障仍然不可避免,会导致数据库中部分数据的丢失甚至破坏数据库,数据库恢复就是为了将数据库从错误状态恢复到某一已知的正确状态。
事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。例如在关系数据库中,一个事务可以是一条SQL语句、一组SQL语句。
事务通常是以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。COMMIT表示提交,ROLLBACK表示回滚,在事务运行的过程中发生某种故障事务不能继续执行,系统就会将事务对数据库的已完成操作全部撤销,从而回滚到事务开始时的状态。
事务的特性:
1.原子性:事务是数据库的逻辑工作单位,事务中包括的操作要么都做,要么都不做
2.一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。事务执行过程中出现故障则称这时的数据库处于不一致性状态。
3.隔离性:一个事务的执行不能被其他事务干扰,并发执行的各个事务之间不能互相干扰
4.持续性(永久性):一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
事务的ACID特性可能遭到破坏的因素有:
转储即DBA定期地将整个数据库复制到磁带或另一个磁盘上保存起来的过程。这些备用的数据称为后被副本。
转储分为:
也可分为:
日志文件是用来记录事务对数据库的更新操作的文件。不同数据库系统采用的日志文件格式并不完全一样,主要有两种格式:以记录为单位的日志文件和以数据块为单位的日志文件
对以记录为单位的日志文件,日志文件中需要登记的内容包括:
以上每一条内容记为一个日志记录(log record)
每个日志记录的内容主要包括:
REDO:重做,正向扫描日志文件,对每个REDO事务重新执行日志文件登记的操作
UDNO:撤销,反向扫描日志文件,对每个UNDO事务的更新操作执行逆操作
COMMIT:提交,将事务中所有对数据库的更新写回到磁盘上的物理数据库中,事务正常结束
ROLLBACK:回滚,事务运行的过程中发生了某种故障,事务不能继续执行,系统将事务中对数据库的所有已完成操作全部撤销,回滚到事务开始时的状态
(1)反向扫描日志文件(即从最后向前扫描日志文件),查找该事务的更新操作
(2)对该事务的更新操作执行逆操作。(来得及或者未来得及写入数据库都没关系)
(3)继续反向扫描日志文件,查找该事务的其他更新操作,并做同样处理
(4)如此继续,直到读到该事务的开始标记
(1)正向扫描日志文件,找出在故障发生前已经提交的事务(这些事务既有BEGIN TRANSACTION记录,也有COMMIT记录),将其事务标记记入REDO队列;同时找出故障发生时尚未完成的事务(这些事务只有BEGIN TRANSACTION记录,无相应的COMMIT记录),将其事务标记记入UNDO队列
(2)对撤销队列中的各个事务执行UNDO操作
(3)对重做队列中的各个事务执行REDO操作
为什么要REDO?考虑已提交事务对数据库的更新可能还留在缓冲区没来得及写入数据库(磁盘)。
(1)装入最新的数据库后备副本,使数据库恢复到最近一次转储时的一致性状态
(2)装入相应的日志文件副本(转储结束时刻的日志文件副本),重做已完成的事务,即扫描日志文件找出需要重做和撤销的事务
多事务执行方式:
事务是并发控制的基本单位
并发控制机制的任务
记号
两个事务T1和T2读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致T1的修改丢失
不可重复读是指事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次的读取结果。
事务T1按一定条件从数据库中读取了某些记录之后,事务T2删除了其中的部分记录,当T1再次按相同的条件读取数据时,发现某些记录神秘消失了。
事务T1按一定条件从数据库中读取某些数据记录后,事务T2插入了一些数据,当T1再次按相同条件读取数据时,发现多了一些数据。
上面两种现象又称为”幻影”现象。
事务T1修改某一数据,并将其写回磁盘
事务T2读取同一数据后,T1由于某种原因被撤销
这时T1已修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一样
T2读到的数据就是“脏”数据,即不正确数据
并发控制主要技术:
排它锁(简记为X),又称为写锁
共享锁(简记为S),又称为读锁
保持数据一致性的常用封锁协议
三级协议的主要区别:
不同的封锁协议使事务达到的一致性级别不同
一级协议:(没有丢失数据修改)
事务T1封锁了数据R
事务T2又请求封锁R,于是T2等待
T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍等待
T4来了,系统又批准,T2又等待…
…
T2有可能永远等待,这就是活锁的情形
避免活锁:采用先来先服务策略
死锁:就是形成了环,T1等待T2,T2等待T1,T1和T2两个事务永远不能结束,形成死锁
两类方法: