文章所涉及的数据库知识皆是参考王珊老师的《数据库系统概论》和哈尔滨工业大学战德臣老师的《数据库系统》课程。
数据库完整性
DBMS应保证DB的一种特性--在任何情况下的正确性、有效性和一致性
广义完整性:语义完整性、并发控制、安全控制、DB故障修复等
狭义完整性:专指语义完整性
DBMS保证完整性
完整性约束规则
integrity constraint = (O,P,A,R)
O:数据集合(约束的对象:列,元组,元组集合)
P:约束条件
A:触发条件
R:响应动作(不满足时怎么办)
数据库完整性分类
按约束对象分类
域完整性约束:施加于某一列上的约束
关系完整性约束条件:施加于table上,或者是对一个关系中的若干元组和另一个关系中的若干元组间的联系
按约束来源
结构约束:模型的约束,例如函数依赖约束,实体完整性,参照完整性,是否允许空值
内容约束:用户自定义完整性
按约束状态
静态约束:要求DB在任一时候都满足的约束,例如Sage应大于0小于150
动态约束:要求DB从一状态变为另一状态时应满足的约束,例如工资只能升不能降
SQL语言实现约束
静态约束:列完整性,表完整性
动态约束:触发器
create table:定义关系模式,定义完整性约束,定义物理存储特性列约束实例
列约束
create table tablename(colname datatype, -- colname列的数据类型datatype
not null -- 列值非空
unique -- 列值唯一
constraint constraintname -- 约束命名为constraintname
primary key -- 列为主键
check(search_cond) -- 列值满足条件search_cond,条件只能使用列当前值
references tablename (colname) on delete cascade | set null) -- 引用tablename的列colname的值,若引用表的某项被删除,对应本表的对应项被删除或者更新为null
create table Student(S# char(8) not null unique, -- 不为空且唯一(主键)
Sname char(10),
Ssex char(2) constraint ctssex check (Ssex = '男' or Ssex = '女') -- 约束名:ctssex,check后跟约束条件
Sage int check(Sage >= 1 and Sage < 150),
D# char(2) references Dept(D#) on delete cascade, -- Student表D#是外键,连接Dept表, on delete set null 表示如果Dept表中某项被删除,对应Student表中置为null
Sclass char(6));
create table Course(C# char(3), Cname char(12), Chours int,
Credit float(1) constraint ctcredit check(Credit >= 0.0 and Credit <= 5.0),
T# char(3) references Teacher(T#) on delete cascade); -- on delete cascade 表示如果Teacher表中某项被删除,则对应在Course表中的该项也被删除
表约束
create table tablename(colname,colname,...),
constraint constraintname -- 为约束名
unique(colname, colname,...) -- 几列值组合在一起是唯一
primary key(colname, colname, ...) -- 几列联合为主键
check(search_condition) -- 元组多列值共同满足的条件,条件中只能使用同一元组的不同列当前值
foreign key(colname, colname,...)
reference tablename(colname, colname, ...)
on delete cascade | set null -- 引用另一个表tablename的若干列的值作为外键
create table Student(S# char(8) not null unique, Sname char(10),
Ssex char(2) constraint ctssex check(Ssex = '男' or Ssex = '女'),
Sage int check(Sage > 1 and Sage < 150), D# char(2) references Dept(D# on
delete cascade, Sclass char(6), primary key(S#)); -- 将S#设为主键
create table Course(C# char(3), Cname char(12), Chours int,
Credit float(1) constraint ctcredit check(Credit >= 0.0 and
Credit <= 5.0), T# char(3) references Teacher(T#) on delete
cascade, primary key(C#), constraint ctcc check(Chours/Credit = 20));
create table SC(S# char(8), C# char(3),
Score float(1) constraint ctscore check(Score >= 0 and
Score <= 100),
foreign key(S#) references student(S#) on delete cascade,
foreign key(C#) references course(C#) on delete cascade)
create table SC(S# char(8) check(S# in (select S# from Student)),
C# char(3) check( C# in (select C# from Course)),
Score float(1) constraint ctscore check(Score > 0 and Score <= 100)
SQL语言实现动态约束性(触发器)
触发器Trigger是一种过程完整性约束,是一段程序,在特定的时刻被自动触发执行,比如在一次更新之前或者在更新之后执行。
基本型式:
create trigger trigger_name -- 定义一个叫trigger_name的触发器
before | after
insert | delete | update of (colname, colname,...)
on tablename -- 在表tablename上作用在colname的某个事件(insert | delete | update)的前后
referencing (corr_name_def, corr_name_def,...) --后面触发事件用到的列名
for each row | for each statement -- 对每一元组,或者是整个操作的所有元组
when (search_condition) -- 如果满足search_condition条件
statement | begin atomic (statement,statement,...) -- 则执行该行操作,如果有多个操作用后面的一段
--corr_name_def定义:
old [row] [as] old_row_corr_name -- 更新前旧元组命别名为old_row_corr_name
new [row] [as] new_row_corr_name -- 更新后的新元组
old table [as] old_table_corr_name -- 更新前的旧表
new table [as] new_table_corr_name -- 更新后的新表
设计触发器当进行Teacher表更新元组时,使其工资智能升不能降
create trigger teacher_chgsal before update of salary on Teacher
referencing new x, old y
for each row when(x.salary < y.salary)
begin
raise_application_error(-20003,'invalid salary on update');
假设student(S#,Sname,SumCourse), SumCourse为该同学已学习课程的门数,初始值为0,以后每选秀一门课程要对其增1,设计一个触发器描述该功能
create trigger sumc after insert on SC
referencing new newi,
for each row
begin
update student set SumCourse = SumCourse + 1
where S# = newi.S#;
end
假设student(S#,Sname, Sage,Ssex,Sclass)中某一学生要变更其主码S#的值,如使其原来的98030101变更为99030131,此时SC表中该同学已选课记录的S#也需自动随其改变。设计一个触发器完成上述功能
create trigger updS# after update S# on student
referncing new newi, old oldi
for each row
begin
update SC set SC.S# = newi.S#
where SC.S# = oldi.S#
end
假设student(S#,Sname, SumCourse),当删除某一同学S#时,该同学的所有选课也都要删除。
create trigger delS# after delete S# on student
referencing old oldi
for each row
begin
delete SC where S# = oldi
end
假设student(S#,Sname,SumCourse),当删除某一同学S#时,该同学的所有选课中的S#都要置为空值
create trigger delS# after delete S# on student
referencing old oldi
for each row
begin
update SC set C# = null
where S# = oldi.S#;
end;
假设Dept(D#,Dname,Dean),而Dean一定是该系教师Teacher(T#,Tname,D#,Salary)中工资最高的教师
create trigger upddean before update Dean on Dept
referencing new newi
for each row when (dean not in
(select Tname from Teacher where D# = newi.D#
and Salary >= all(select salary from Teacher where D# = newi/D#))
begin
raise_application_error(-20003,'invalid Dean on update');
end;
数据库安全性
DBMS安全机制
自主安全性机制:存取控制,通过权限在用户之间的传递,是用户自主管理数据库安全性
强制安全机制:通过对数据和用户强制分类,使不同类别用户能够访问不同类别的数据
推断控制机制:防止通过历史信息,推断出不该被其知道的信息。防止通过公开信息推断出私密信息。
数据加密存储机制:通过加密、解密保护数据,密钥,加密/解密方法与传输
DBMS专门提供一个DBA账户,该账户是一个超级用户(系统用户),通过DBA授予某账户一定的权限
安全性控制规则
AccessRule = (S,O,t,P)
S:请求主体(用户)
O:访问对象
t:访问权力
P:谓词
AccessRule通常存放在数据字典或系统目录中
用户多时,可按用户组建立访问规则
访问对象可大可小
权力包括:增删改查建
谓词:拥有权力需满足的条件
自主安全性控制实例
自主安全性实现方式
1.存储矩阵
2.视图
通过视图可以限制用户对关系中某些数据项的存取,参照之前视图章节
SQL语言的用户与权力
普通用户账户级别用户超级用户DBA
级别1:select
级别2:insert,update,delete
级别3:create,alter,drop
高级别的权力自动包含低级别权力,同时也可以授予低级别用户权力
授权命令基本型式
grant all privileges | privilege -- 授予所有权力或者select|insert|update|delete|all priviledges权限中的某个或某几个
on tablename | viewname -- 在某个表或视图上操作
to public | user-id -- 授予所有有效用户的权力或某个用户账户
with grant option -- 允许被授权着传播权力
假定高级领导奥维Emp0001,部门领导为Emp0021,员工管理员为Emp2001,收发员为Emp5001(均为Userld,也即员工P#)
grant all priviledges on Empolyee to Emp2001;
grant select on EmpV2 to Emp5001;
grant select on EmpV3 to public;
grant select on EmpV4 to Emp0021;
收回授权的基本型式
revoke all privilEges | (priv,priv,...) -- 收回全部权力或某项或某几项权力
on tablename | viewname
from public | (user,user,...)
-- demonstrate
revoke select on employee from UserB;
授权过程
一、DBA创建DB,为每个用户创建一个账户
创建:UserA,UserB,UserC,UserD,UserE
二、DBA授予某用户账户级别权力
授予UserA
三、具有账户级别的用户可以创建基本表或视图,他也自动成为该表或该视图的属主账户,拥有该表或该视图的所有访问权力
UserA创建Employee,UserA就是Employee表的属主账户
四、拥有属主账户的用户可以将其中的一部分权力授予另外的用户,该用户也可以将权力进一步授权给其他用户
UserA将读权限授予UserB,UserB又将其拥有的权限授予UserC,权力不断传递下去
注意授权的传播范围
强制安全性机制
安全性分级:绝密,机密,可信,无分类
访问规则:
高级别用户可读取低级别数据对象,反之低级别用户不能读取高级别数据对象
低级别用户写的数据对象,高级别的用户不能修改。
强制安全性机制的实现
关系模式:
关系模式加入安全性分级特性: