【数据库】总结

第一章
概念模型(ER图)
椭圆是属性
矩形是实体
菱形为联系

概念模型到关系模型转化
主码下面要加下划线

1-m联系
实体型->关系模式
将1端主码连同联系属性放入n端属性中

1-1联系
实体型->关系模式
任意一端主码连同联系属性放入到另外一端实体当中

n-m联系
实体型->关系模式
产生一个新关系,关系名为联系名,将两端实体的主码连同关系属性

数据库系统的三级模式结构
概念
数据库的三级模式结构是由外模式、模式、内模式三级构成。
模式,也成逻辑模式,是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图,一个数据库只有一个模式。
外模式,也称子模式或用户模式,它是数据库用户能够看见或使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。外模式通常是模式的子集。一个数据库可以有多个外模式。
内模式,也称存储模式,一个数据库只有一个内模式。它是数据物理结构和存储方式描述,是数据在数据库内部的组织方式。

优点
外模式使得数据库安全性大大提高。
外模式/模式映像、模式/内模式映像使程序具有较高的逻辑独立性和物理独立性,使得数据定义和描述可以从应用程序中分离出去,另外,由于数据的存取由数据管理系统管理,从而简化了应用程序的编制,大大减少了应用程序维护和修改。

数据库第二章(关系数据库)
关系完整性
实体完整性
若属性(指一个或一组属性)A是基本关系R的主属性,则A不能取空值(null)。

参照完整性
若属性(或者属性组)F是基本关系R的外码,它与基本关系S的主码Ks相对应(基本关系R和S不一定是不同的关系),则对于R中每个元组在F上的值必须
或者取空值
或者等于S中某个元组的主码值

补充:外码
设F是基本关系R的一个或一组属性,但不是关系R的码,Ks是基本关系S的主码。如果F与Ks相对应,则称F是R的外码,并称基本关系R为参照关系,基本关系S为被参照关系。关系R和关系S不一定是不同的关系。

用户定义完整性
针对某一具体关系数据库的约束条件,它反映某一具体应用所涉及的数据必须满足的语义要求。如定义性别只能取男女,成绩为0-100等。

关系代数
查询至少选修1 号课程和3 号课程的学生号码
查询选修了2 号课程的学生的学号
查询至少选修了一门其直接先行课为5 号课程的学生姓名
查询选修全部课程的学生学号
求选修了1 号或2 号课程的学生号
检索刘老师所授课程的课程号和课程名
检索年龄大于23 岁的男学生的学号和姓名
检索学号为S3 学生所学课程的课程名与任课教师名
检索至少选修刘老师所授课程中一门课程的女学生姓名
检索WANG 同学不学的课程的课程号
检索至少选修两门课的学生学号
检索全部学生都选修的课程的课程号和课程名
检索选修课程包含LIU 老师所授全部课程的学生学号

传统的集合运算

R∪S={t|t∈R∨t∈S}
t为元组变量

R-S={t|t∈R∧t∉S}
t为元组变量

R∧S={t|t∈R∧t∈S}
t为元组变量

笛卡尔积

R×S={ts tr|tr∈R∧ts∈S }
t为元组

专门的关系运算
选择
投影
连接

关系验算语言
第三章
数据定义
模式定义
创建 create schema
删除 drop schema

表定义
创建 create table
删除 drop table
修改 alter table

创建学院表dept 学院号是主码,学院名不可为空
create table dept
(
dno char(2),
dname char(20),
dtel char(10),
primary key(dno)
);

建立学生表,学号是主码,姓名取值唯一,性别不能为空
create table student
(
sno char(10) primary key,
sname char(20) unique,
ssex char(2) not null,
foreign key(dno) references dept(dno)
);
删除表
DROP TABLE Student [restrict|cascade];

视图
创建 create view
删除 drop view
详见视图部分

索引定义
创建 create index
删除 drop index
修改 alter index
建立索引的目的:加快查询速度

create [unique][cluster]
index <索引名>
on <表名>
(<列名>[<次序>][,<列名>[<次序>]]…);
unique:唯一索引,每个索引项只对应唯一的记录类型
cluster:聚簇索引,索引项的顺序与表中记录的物理顺序一致的索引组织。

drop index<索引名>

数据更新
插入数据
插入时会检查所插入的元组是否满足完整性规则
实体完整性
参照完整性
用户定义完整性
not null
unique
值域约束

插入元组(插入一条记录)

格式:
insert into<表名>[(<属性列1>[,<属性列2>…])]

将一个新学生元组 ( 学号 :200215128 ;姓名 : 陈冬 ; 性别 : 男 ; 所在系 :CS ; 年龄 :18 岁) 插入到Student 表中 。
insert into s(sno,sname,ssex,sdept,sage)
values(‘200215128’,‘陈东’,‘男’,‘cs’,18);

对每一个系 , 求学生的平均年龄 , 并把结果存入数据库
create table dept_age
(
dept char(15) primary key,
avg_age smallint
);
insert into dept_age(dept,avg_age)
select sdept,avg(sage)
from s
group by sdept;

插入子查询结果(插入多条记录)

修改数据
update <表名>
set <列名>=<表达式>[,<列名>=<表达式>…]
[where <条件>];

修改某一个元组的值

将学生200215121 的年龄改为22 岁
update s
set sage=22
where sno=‘200215121’;

修改多个元组的值

所有教师工资上调5%
update prof
set sal =sal*1.05;

带有子查询的修改语句

将IS系全体学生成绩清零
update sc
set grade=0
where sno in(
select sno from s
where sdept=‘IS’
);

当某同学1号课的成绩低于该课程平均成绩时,将该同学该门课成绩提高5%。
update sc
set grade=grade*1.05
where cno=‘1’ and grade<(select avg(grade) from sc where cno=‘1’);

删除数据
删除某一个元组的值

删除多个元组的值

带子查询的删除语句

删除有四门不及格课程的所有同学信息。
delete from s
where sno in (
select sno from sc
where grade<60
group by sno
having count(*)>=4
);

视图
虚表,是从一个或几个基本表(或视图)导出的表
只存放视图的定义,不存放视图对应的数据
基表中的数据发生变化,从视图中查询出的数据也随之改变

定义视图
create view
<视图名> [<列名>[,<列名>…]]
as <子查询>
[with check option];

建立is系学生视图
create view is_student
as
select sno,sname,sage
from s
where sdept=‘IS’;

建立IS 系学生的视图 , 并要求进行修改和插
入操作时仍需保证该视图只有IS
create view is_student
as
select sno,sname,sage
from s
where sdept=‘IS’
with check option;

with check option
如上题,更新时自动加上sdept=‘IS’

删除视图
DROP VIEW < 视图名>[CASCADE] ;
PS:cascade 是级联

查询视图
更新视图
视图的作用
视图能够简化用户的操作
视图使用户能以多种角度看待同一数据
视图对重构数据库提供了一定程度的逻辑独立性
视图能够对机密数据提供安全保护
适当的利用视图可以更清晰的表达查询

嵌入式sql
database.cpp
数据查询
单表查询
选择表中若干列
select 后面列出目标列表达式

目标列表达式

算术表达式
字符串常量
函数(count, sum, avg, min, max)
列别名(可使用列别名改变查询结果的列标题)
选择表中若干元组
查询结果可能出现重复元组,通过distinct去重

常用的查询条件

比较(=, >, <. >=, <=, !=, <>)

确定范围(between and, not between and)

确定集合(in, not in)

select sname,ssex
from s
where sdept in(“CS”, “MA”,“IS”)

字符匹配(like, not like)

[not] like ‘匹配串’ escape ‘换码字符’
%匹配0个及以上任意字符, _匹配任意单个字符
多重条件(and, or, not)

涉及空值的查询

选修1号课的不及格的学生及缺考的学生学号。
select sno from sc
where cno=‘1’ and grade<60
union
select sno from sc
where cno=‘1’ and grade is null

order by 子句
按照系好升序列出老师姓名,所在系别,同一系中老师按姓名降序排序。
select pname,dno
from prof
order by dno, pname desc;

升序 asc (默认) 降序 desc
聚集函数
计数 count(* | [distinct | alll] <列名>)
计算总和 sum([distinct | all] <列名>)
计算平均值 avg([distinct | all] <列名>)
最大最小值 max([distinct | all] <列名>) min([distinct | all] <列名>)
group by 子句
结合聚集函数
having语句进行对分组筛选(组为单位) where对记录进行筛选(记录为单位),先进行where再进行having
连接查询
等值与非等值连接查询
例题:查询 每个学生及其选修课程的情况
select s.,sc.
from s,sc
where s.sno=sc.sno
自然连接
查询每个学生及其选修课程的情况,用自然连接完成
select s.sno, sname,sage,ssex,sdept,cno,grade
from s,sc
where s.sno=sc.sno

自身连接
例题:查询每一门课的间接选修课(先修课的先修课)
select first.cno,second.pno
from sc first,sc second
where first.pno=second.cno

外连接
查询每个学生及其选修课程的情况
select s.sno,sname,ssex,sage,cno,grade
from s left outer join sc on(s.sno=sc.sno)

左外连接

左边关系中的任何元组t都会出现在结果表中
格式:
R left outer join S on(R.c=S.c)

右外连接

右边关系的任何元组t都会出现在结果表中
格式:
R right outer join S on(R.c=S.c)

全外连接

是前两者的并
格式:
R full outer join S on(R.c=S.c)

复合条件连接
WHERE子句中含多个连接条件和限定

查询选修2号课程且成绩在90分以上的所有学生的学号和姓名
select s.sno,sname
from s,sc
where s.sno=sc.sno
and sc.cno=‘2’
and sc.grade>90

选出既学过1号课程,又学过2号课程的学生学号
select sno
from sc sc1,sc sc2
where sc1.sno=sc2.sno
and sc1.cno=‘1’
and sc2.cno=‘2’

嵌套查询
一个SELECT-FROM-WHERE 语句称为一个查询块
将一个查询块嵌套在另一个查询块的WHERE 子句或HAVING 短语的条件中的查询称为嵌套查询
子查询的限制:不能使用order by子句
有些嵌套查询可以用连接查询代替

带有in谓词的子查询
查询与 “ 刘晨 ” 在同一个系学习的学生姓名
select sname
from s s1
where s1.sdept in(
select sdept from s s2
where s2.sname=‘刘晨’
);
ps:该查询是不相关子查询,s1 s2可以省略

查询选修了课程名为 “ 信息系统 ” 的学生学号
和姓名
select s.sno,sname
from s,sc
where s.sno=sc.sno and sc.cno in (
select cno from c
where c.cname=‘信息系统’
);
这种情况是1对1的 用连接查询比较方便
select s.sno,sname
from s,sc,c
where s.sno=sc.sno and sc.cno=c.cno and c.cname=‘信息系统’;

求两门课以上不及格课程学号以及其平均成绩
select sno,avg(grade)
from sc
where sc.sno in (
select sno from sc
where grade < 60
group by sno
having count(*)>2
)
group by sno

列出没学过编译原理课程的所有同学姓名
select sname
from s
where sno not in (
select sno from sc,c
where sc.cno=c.cno and cname=‘编译原理’
);

带有比较运算符的子查询
子查询一定要跟在比较符之后,当确切知道内层查询返回单值时,可用比较运算符(>,<,<=,>=,!=或者<>)

找出每个学生超过他选修课程平均成绩的
课程号 。
select sno,cno
from sc sc1
where sc1.grade>(
select avg(grade)
from sc sc2
where sc2.cno=sc1.cno
)

带有any(some)或all谓词的子查询
ANY 大于子查询结果中的某个值
ALL 大于子查询结果中的所有值
< ANY 小于子查询结果中的某个值
< ALL 小于子查询结果中的所有值
= ANY 大于等于子查询结果中的某个值
= ALL 大于等于子查询结果中的所有值
<= ANY 小于等于子查询结果中的某个值
<= ALL 小于等于子查询结果中的所有值
= ANY 等于子查询结果中的某个值
=ALL 等于子查询结果中的所有值(无意义)
!=(或<>)ANY 不等于子查询结果中的某个值
!=(或<>)ALL 不等于子查询结果中的任何一个值

any 任意一个值
all 所有值
带有exists谓词的子查询
查询所有选修了1 号课程的学生姓名
select sname
from s
where exists(
select * from sc
where sc.cno=‘1’ and sc.sno=s.sno
)

查询与 “ 刘晨 ” 在同一个系学习的学生姓名
select sname
from s s1
where exists(
select * from s s2
where s2.sdept=s1.sdept and s2.sname=‘刘晨’
)

查询选修了全部课程的学生姓名 (没有一门课程是他不选修的)。
select sname
from s
where not exists(
select * from sc where not exists(
select * from c
where c.cno=sc.cno and s.sno=sc.sno
)
)

集合查询
参加集合操作的个查询结果的列数必相同;
对应项的数据类型也必须相同

并操作(union)
交操作(intersect)
差操作(except)
基于派生表的查询
from (SELECT Sno FROM SC WHERE Cno=’ 1 ') as sc1
第五章、关系数据理论
函数之间依赖关系
完全函数依赖(好的依赖关系)
部分函数依赖
传递函数依赖
判断范式
1NF
一个关系模式所以属性都是不可分的数据项

2NF
R∈1NF,且每一个非主属性完全函数依赖于任何一个候选码,则R∈2NF

3NF
设关系模式R<U,F>∈1NF,若R中不存在这样的码X,属性组Y及非主属性Z(Z不是Y子集)使得X->Y,Y->Z成立,Y ->X,则称R<U,F>∈3NF

BCNF
关系模式R<U,F>∈1NF,若X->Y且Y不是X子集时,X必含有码,则R<U,F>∈BCNF

证明
若R为3NF,证明其为2NF
若R是BCNF,证明其为3NF
模式分解
原则:消除不合理依赖,保留好的依赖,保持无损连接。

1NF -> 2NF
消除非主属性对码的部分函数依赖

2NF -> 3NF
消除非主属性对码的传递函数依赖

3NF -> BCNF
消除主属性对码的部分和传递函数依赖

属性集闭包计算及公理系统
属性集闭包计算:
已知关系模式R<U,F>,其中,
U={A,B,C,D,E}
F={AB->C,B->D,C->E,EC->B,AC->B}
求(AB)_F^+

数据库设计
需求分析
了解与分析用户需求(包括数据和处理),是最为繁琐的一步。

概念结构设计
通过对用户需求进行综合,归纳和抽象,形成一个独立与具体数据库管理系统的概念模型(如er图)。

逻辑结构设计
将概念结构转化为某个数据库管理系统所支持的数据模型,并对其进行优化。

数据库物理设计
为逻辑数据模型选取一个最适合应用环境的物理结构(包括存储结构和存取方法)。

数据库实施
设计人员运用数据库管理系统提供的数据库语言及其宿主语言,根据逻辑设计和物理设计的结果建立数据库,编写与调试应用程序,组织数据入库,并进行试运行。

数据库运行与维护
数据库应用系统经过试运行后即可投入正式运行。在数据库系统运行过程中必须不断的对其进行评估,调整和修改。

第七章、数据库恢复
事物:事务(Transaction)是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。

BEGIN TRANSACTION;
COMMIT;
ROLLBACK;
事务通常是以begin transaction开始,以commit或者rollback结束。
commit:表示提交,及提交事务的所有操作。
rollback:表示回滚,事务运行过程中出现了某种故障,事务不能正常执行,系统将事务中对数据库所有已完成的操作全部撤销。

事务四个特性:原子性、一致性、隔离性、持续性。

故障种类
事务故障
某个事务在运行过程中由于种种原因未运行至正常终止点就夭折了。

– 输入数据有误
– 运算溢出
– 违反了某些完整性限制
– 某些应用程序出错
– 并行事务发生死锁

系统故障
系统故障是指造成系统停止运转的任何事件,使得系统要重新启动。

– 整个系统的正常运行突然被破坏
– 所有正在运行的事务都 非正常终止
– 内存中 数据库缓冲区的信息全部丢失
– 外部存储设备上的数据未受影响

介质故障
介质故障是指存储数据库的设备( 如硬盘) 发生故障,使存储在其上的数据部分丢失或全部丢失。

磁盘损坏、
磁头碰撞、
操作系统的某种潜在错误
瞬时强磁场干扰。

恢复实现技术
数据转储(备份)
数据库管理员定期地将整个数据库复制到磁带,磁盘或者其他存储介质上保存起来的过程。

数据库转储还可分为两个方式:海量转储(每次转储全部数据库)和增量转储(每次只转储上一次转储后更新的数据),其和两种转储状态可两两组合。

静态转储

在系统无运行事务时进行的转储操作。

在转储操作开始的时刻数据库处于一致性状态,而转储期间不允许(或不存在)对数据库的任何存取、修改活动。

动态转储

是指转储期间允许对数据库进行存取或修改。

必须把转储期间各事务对数据库的修改活动登记下来,建立日志文件。

日志文件
日志文件的格式和内容

是用来记录事务对数据库的更新操作的文件。

以记录为单位

各个事务的开始标记(BEGIN TRANSACTION)
各个事务的结束标记(COMMIT 或ROLLBACK)
各个事务的所有更新操作
这三个构成日志文件中的一个日志记录。

每个日志记录内容

事务标识
操作类型(插入、删除或修改)
操作对象
更新前数据的旧值(对插入操作而言,此项为空值)
更新后数据的新值(对删除操作而言, 此项为空值)
以数据块为单位

– 事务标识
– 更新前的数据块(对插入操作而言,此项为空值)
– 更新后的数据块(对删除操作而言, 此项为空值)

日志文件的作用

进行事务故障恢复
进行系统故障恢复
介质故障恢复(协助后备副本进行)
登记日志文件

登记次序严格按照并发事务执行的时间次序

先写日记文件,后写数据库

原因:
– 写数据库和写日志文件是两个不同的操作;
– 在这两个操作之间可能发生故障。
– 如果先写了数据库修改,而在日志文件中没有记登
这个修改,则以后就无法恢复这个修改了;
– 如果先写日志,但没有修改数据库, 按日志文件恢
复时,只不过是多执行一次不必要的UNDO 操作,并
不会影响数据库的正确性。

具有检查点的恢复技术
从重新开始文件中找到最后一个检查点记录在日志文件中的地址,由该地址在日志文件中找到最后一个检查点记录;
由该检查点记录得到检查点建立时刻所有正在执行的事单务清单ACTIVE-LIST ,建立两个事务队列
– UNDO-LIST
– REDO-LIST
把首先把ACTIVE-LIST 暂时放入UNDO-LIST 队列,REDO队列暂为空。
从检查点开始正向扫描日志文件,直到日志文件结束
– 如有新开始的事务Ti, 把Ti 暂时放入UNDO-LIST 队列
– 如有提交的事务Tj ,把Tj 从UNDO-LIST 队列移到REDO-LIST 队列
对UNDO-LIST 中的每个事务执行UNDO 操作, 对REDO-
LIST 中的每个事务执行REDO
恢复策略
事务故障的恢复
(a) 反向扫描文件日志(即从最后向前扫描日志文件),查找该事务的更新操作。
(b) 对该事务的更新操作执行逆操作。即将日志记录中 “ 更新前的值 ” 写入数据库。
插入操作, “ 更新前的值 ” 为空,则相当于做删除操作
删除操作, “ 更新后的值 ” 为空,则相当于做插入操作
修改操作,则用 “ 更新前的值 ”代替"更新后的值"
© 继续反向扫描日志文件,查找该事务的其他更新操作,并做同样处理。
(d) 如此处理下去,直至读到此事务的开始标记,事务故障恢复就完成了。

系统故障的恢复
总:撤销故障发生时未完成的事务,重做已完成的事务。

正向扫描日志文件(即从头扫描日志文件),生成如下两个队列。
Redo 队列: 在故障发生前已经提交的事务
Undo 队列: 故障发生时尚未完成的事务

对Undo 队列事务进行Undo处理:
反向扫描日志文件,对每个Undo事务的更新操作执行逆操作,即将 “ 更新前的值 ” 写入数据库。(回滚)

对Redo 队列事务进行REDO 处理:
正向扫描日志文件,对每个REDO 事务重新执行日志文件登记的操作,即将 “ 更新后的值 ” 写入数据库。(重做)

介质故障的恢复
重装数据库
装入最新的后备数据库副本,使数据库恢复到最近一
次转储时的一致性状态。
重做已完成事务
装入有关的日志文件副本(转储结束时刻的日
志文件副本),重做已完成的事务。
第八章、并发控制
事务并发执行带来的问题
会带来数据不一致性

丢失修改
丢失修改是指事务1与事务2从数据库中读入同一数据并修改,事
务2的提交结果破坏了事务1提交的结果,导致事务1 的修改被丢失。

不可重复读
不可重复读是指事务1读取数据后,事务2执行更新操作,使事务1无法再现前一次读取结果 。

修改

事务1 读取某一数据后:事务2对其做了修改, 当事务1再次读该数据时,得到与前一次不同的值。

删除

事务2删除了其中部分记录 ,当事务1 再次读取数据时,发现某些记录神秘地消失了。

插入

事务2 插入了一些记录 ,当事务1 再次按相同条件读取数据时,
发现多了一些记录。

读脏数据
事务1修改某一数据,并将其写回磁盘,事务2读取同一数据后 读取同一数据后,事务1由于某种原因被撤消 。这时事务1已修改过的数据恢复原值,事务2读到的数据就与数据库中的数据不同,是不正确的数据,又称为 “ 脏 ” 数据 。

*
*就是事务T 在对某个数据对象(例如表、记录等)操作之前,先向系统发出请求,对其加锁。
加锁后事务T 就对该数据对象有了一定的控制,在事务T释放它的锁之前,其它的事务不能更新此数据对象。

基本*类型
共享锁(s锁,又称为读锁)

若事务T对数据对象A加上S锁,则其它事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。

排它锁(X锁,又称为写锁)

若事务T对数据对象A 加上X 锁,则只允许T读取改和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。

*协议
一级*协议

事务T在修改数据R之前必须先对其加X锁,直到事务结束(commit或rollback)才释放。

可防止丢失修改

如果是读数据,不需要加锁的,所以它不能保证可重复读和不读“脏”数据。

二级*协议

1级*协议+ 事务T在读取数据R前必须加先加S锁,读完后即可释放S锁。

2级*协议可以防止丢失修改和读“脏”数据。

由于读完数据后即可释放S 锁,所以它不能保证可重复读。

三级*协议

1 级*协议+事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。

3级*协议可以防止丢失修改和读“脏”数据和不可重复读。

活锁和死锁
活锁
由于系统调度原因,某些事物的加锁请求得不到响应而永远等待。

策略:可采用先到先服务的策略。

死锁
两个或多个事务都已*了一些数据对象,然后又都请求对已被其他事务*的数据对象加锁,从而出现死等待。

死锁的预防

这两种策略并不太适合数据库的特点,因此采用诊断并解除的方法。

一次*法

要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行 。

难于事先精确确定*对象
降低并发度

顺序*法

顺序*法是预先对数据对象规定一个*顺序,所有事务都按这个顺序实行*。

维护成本高
难于实现

死锁的诊断和解除

诊断

超时法

如果一个事务的等待时间超过了规定的时限,就认为发生了死锁。

实现简单

若时限设置过短,有可能误判死锁
若时限设置过长,容易发现不到死锁。
等待图法

用事务等待图动态反映所有事务的等待情况。并发控制子系统周期性地生成事务等待图,并进行检测。

解除

选择一个处理死锁代价最小的事务,将其撤消,释放此事务持有的所有的锁,使其它事务能继续运行下去。

并发操作的可串行性
将所有事务串行起来的调度策略一定是正确的调度策略。

多个事务的并行执行是正确的, 当且仅当其结果与按某一次序串行地执行它们时的结果相同。这种并行调度策略称为可串行化的调度。

两段锁协议
事务分为两个阶段

并行执行的所有事务均遵守两段锁协议,则对这些事务的所有并行调度策略都是可串行化的。

一次*法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行,因此,一次*法遵守两段锁协议;
但是两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此,遵守两段锁协议的事务可能发生死锁。
扩展阶段
第一阶段获得锁,也称为扩展阶段,在这个阶段,事务可以申请获得数据项任何类型锁,但是不能释放任何锁。

收缩阶段
第二阶段释放锁,也称为收缩阶段,在这个阶段,事务可以释放数据项任何类型锁,但是不能申请任何锁。

第九章、数据库安全性
保护数据库以防止不合法使用所造成的的数据泄露,更改或破坏。

其他的还有
用户层面:用户标记(用户身份鉴别)
硬盘层面:密码方式存储
视图(把要保密的数据隐藏起来)

存取控制
存取控制机制
定义用户权限

定义用户权限,并将用户权限登记到数据字典中。

合法权限检查

根据安全性规则进行安全性检查,若用户请求超出了定义的权限,则系统拒绝操作。

两种存取控制方法
自主存取控制

用户对于不同的数据库对象有不同的存取权限。
不同用户对同一对象也有不同的权限。
用户还可将其拥有的存取权限转授给其他用户。

授权:授予

grant <权限>[,<权限>]…
on <对象类型> <对象名>[,<对象类型><对象名>]…
to <用户>[,<用户>]…
[with grant option]

WITH GRANT OPTION子句:
指定:可以再授予
没有指定:不能传播

(1) 把查询Student表权限授给用户U1
GRANT SELECT
ON TABLE Student
TO U1;
(2) 把对Student表和Course表的全部权限授予用户U2和U3
GRANT ALL PRIVILIGES
ON TABLE Student, Course
TO U2, U3;
(3) 把对表SC的查询权限授予所有用户
GRANT SELECT
ON TABLE SC
TO PUBLIC;
(4) 把查询Student表和修改学生学号的权限授给用户U4
GRANT UPDATE(Sno), SELECT
ON TABLE Student
TO U4;

授权:收回

REVOKE <权限>[,<权限>]…
ON <对象类型> <对象名>,…
FROM <用户>[,<用户>]
[CASCADE|RESTRICT];

cascade:级联收回 系统只收回直接或间接从U5处获得的权限

强制存取控制

每个数据库对象被标记以一定的密级,每一个用户也被授予某一个密级的许可证。对于任意一个对象,只有具有合法许可证的用户才可以存取。

主体与客体

主体:是系统中的活动实体,既包括数据库管理系统所管理的实际用户,也代表用户的各个进程。
客体:是系统中的被动实体,是受主题操纵的,包括文件、基本表、索引、视图等。

规则

当主体许可证级别大于等于客体密级时,该主体才能读取响应的客体
当主体许可证级别小于等于客体密级时,该主体才能写相应的客体。

审计
将用户对数据库的所有操作自动记录下来,放入到审计文件中。

设置审计功能 (AUDIT)
对修改SC表结构或修改SC表数据的操作进行审计
AUDIT ALTER,UPDATE
ON SC;

取消审计功能 (NOAUDIT)
取消对SC表的一切审计
NOAUDIT ALTER,UPDATE
ON SC;

第十章、数据库完整性
数据库完整性是指数据的正确性和相容性。
正确性:数据是符合现实世界语义反应当前实际状况的;
相容性:数据库同一对象在不同关系表中的数据是符合逻辑的。

实体完整性
检查与违约处理
检查主码值是否唯一,如果不唯一则拒绝插
入或修改
检查主码的各个属性是否为空,只要有一个
为空就拒绝插入或修改

参照完整性
CREATE TABLE SC
(Sno CHAR(9) NOT NULL, ,
Cno CHAR(4) NOT NULL, ,
Grade SMALLINT, ,
PRIMARY KEY (Sno ,Cno ),
FOREIGN KEY (Sno) REFERENCES Student(Sno)
ON DELETE CASCADE /* 级联删除SC 表中相应的元组*/
ON UPDATE CASCADE, /* 级联更新 新SC 表中相应的元组 组*/
FOREIGN KEY (Cno) REFERENCES Course(Cno)
ON DELETE NO ACTION /* 当删除course 表中的元
组造成了与SC 表不一致 时 拒绝删除*/
ON UPDATE CASCADE /* 当更新course 表中的cno时 时 , 级
联更新SC 表中相应的元组*/);

违约处理
拒绝(NO ACTION)执行(默认策略)
级联(CASCADE)操作
设置为空值(SET-NULL)

用户定义完整性
不满足则拒绝执行

属性上约束条件
不满足则拒绝执行

不允许空值 not null
列值唯一 unique
用check语句设定 如ssex值允许取’男’和’女’ check( ssex in(‘男’,‘女’))
元组上约束条件
最后加check

当学生的性别是男时,其名字不能以Ms.打头。
CREATE TABLE Student
(Sno CHAR(9),
Sname CHAR(8) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno),
CHECK (Ssex=‘女’ OR Sname NOT LIKE’Ms.%’)
/定义了元组中Sname和 Ssex两个属性值之间
的约束条件/
);

触发器
触发器(Trigger)是用户定义在关系表上的一类由事件驱动的特殊过程。

定义触发器
定义语句

create trigger <触发器名>
{before|after} 触发事件 on <表名>
referencing new|old row as<变量>
for each {row|statement}
begin
执行 内容
end

例题

【1】当删除某一同学Sno时,该同学所有选课也要删除,请用触发器实现。
create trigger dels
after delete on s
referencing old oldi
for each row
begin
delete from sc where sno=oldi.sno
end;

【2】对sc表的grade属性进行修改时,若分数增加了10%,则将此操作记录到另一表sc_u(sno,cno,oldgrade,newgrade)中。
create trigger sc_t
after update of grade on sc
referencing
oldrow as oldtuple
newrow as newtuple
for each row
when(newtuple.grade>=1.1*oldtuple.grade)
insert into sc_u(sno,cno,oldgrade,newgrade)
values(oldtulpe.sno,oldtuple.cno,oldtuple.grade,
newtuple.grade)

激活触发器
执行该表上的before触发器
激活该触发器对应的sql语句
执行该表上的after触发器
删除触发器
触发器必须是已经创建的触发器
只能由具有相应权限的用户删除
PS:只有表的拥有者能创建触发器

drop trigger <触发器名> on <表名>;

上一篇:MySQL,SQL语句执行顺序


下一篇:2020-11-25