重点与难点

  • 数据库完整性的概念,完整性规则,静态约束,动态约束(触发器)
  • 数据库安全性的概念,安全性访问规则,权利与授权

一. 数据库完整性的概念与分类

1. 数据库完整性的定义

数据库完整性(DB Integrity)是指DBMS应保证的DB的一种特性——在任何情况下的正确性、有效性和一致性。

  • 广义完整性:语义完整性、并发控制、安全控制、DB故障恢复等;
  • 狭义完整性:专指语义完整性,DBMS通常有专门完整性管理机制与程序来处理语义完整性问题(本讲专指)

关系模型中完整性要求:实体完整性、参照完整性、用户自定义完整性

数据库设计中,在E-R图/IDEF1X图中有很多完整性约束条件

2. 数据库完整性的问题

不正当的数据库操作,如输入错误、操作失误、程序处理失误等,会引发数据库完整性问题。

数据库完整性管理的作用:

  • 防止和避免数据库中不合理数据的出现
  • DBMS应尽可能地自动防止DB中语义不合理现象

3. 保证数据库完整性

image-20220313212002619

  • DBMS允许用户定义完整性约束规则(DDL)
  • 当DB更新操作时,DBMS自动按照完整性约束条件进行检测

完整性约束条件(规则)的一般形式:Integrity Constraint ::= (O, P, A, R)

O:数据集合(约束对象),P:谓词条件(什么样的约束),A:触发条件(检查时候),R:响应动作(不满足时操作)

4. 数据库完整性分类

按约束对象分类

  • 域完整性约束条件:施加某一列上,更新候选值是否接受约束条件,孤立
  • 关系完整性约束条件:施加于关系/Table上,更新候选元组或者是关系的若干元组的联系是否接受约束条件
    • image-20220313213219791

按约束来源分类

  • 结构约束:来自于模型的约束,如函数依赖约束、主键约束(实体完整性)、外键约束(参照完整性),只关心数值相等与否、是否允许空值等;
  • 内容约束:来自于用户的约束,如用户自定义完整性,关心元组或属性的取值范围。

按约束状态分类

  • 静态约束:DB在任何时候都应该满足的约束,年龄在0到150之间——列(域)/表(关系)完整性约束
  • 动态约束:DB状态转变时应该满足的约束,如工资只升不降——触发器

二. 利用 SQL 语言实现数据库的静态完整性

image-20220314115117586

1. SQL语言实现约束方法——Create Table

1
2
3
4
5
6
CREATE TABLE tablename
((colname datatype [DEFAULT {default_constant | NULL}] [col_constr {col_constr...}]
|, table_constr
{, {colname datatype [DEFAULT {default_constant | NULL}] [col_constr {col_constr...}]
|, table_constr}
...});

表约束前加逗号,而列约束通常和列的声明结对出现。

1.1 Col_constr 列约束

1
2
3
4
5
{ NOT NULL |
[Constraint constraintname]
{ Unique | Primary Key | Check (Search_cond)
| References tablename [(colname)] [On Delete {Cascade | Set NULL}]}
}

References:引用另一表的列(外键)。如有ON DELETE CASCADE 或ON DELETE SET NULL语句,则删除被引用表的某列值v 时,要将本表该列值为v 的记录删除或列值更新为 null;缺省为无操作 。

例:

1
2
3
4
5
6
Create Table Student (Sid char(8) not null unique,
Sname char(10),
Ssex char(2) constraint ctssex check (Ssex=‘男’ or Ssex=‘女’),
Sage integer check (Sage>=1 and Sage<150),
Did char(2) references Dept(Did) on delete cascade,
Sclass char(6));

1.2 Table_constr 表约束

1
2
3
4
5
6
7
8
[Sonstraint constraintname]
{Unique (colname {, colname ...}) // 几列组合是唯一的
| Primary Key (colname {, colname ...}) // 几列联合为主键
| Check (Search_Condition)
| Foreign Key (colname {, colname ...})
References tablename [colname {, colname ...}]
[On Delete Cascade] // 引用另一表的若干列的值作为外键
}

例:

1
2
3
4
5
6
Create Table Course (Cid char(3) ,Cname char(12), Chours	integer,
Credit float(1) constraint ctcredit check
(Credit >=0.0 and Credit<=5.0 ),
Tid char(3) references Teacher(Tid) on delete cascade,
primary key(Cid),
constraint ctcc check(Chours/Credit = 20));
1
2
3
4
Create Table SC (Sid char(8), Cid char(3), 
Score float(1) constraint ctscore check (Score>=0.0 and Score<=100.0),
forergn key (Sid) references student(Sid) on delete cascade,
forergn key (Cid) references course(Cid) on delete cascade);

1.3 约束中的Check

check 中的条件可以是 Select-From-Where 内任何Where后的语句,包含子查询

1
2
3
Create Table SC (Sid char(8) check( Sid in (select Sid from student)),
Cid char(3) check( Cid in (select Cid from course)) ,
Score float(1) constraint ctscore check (Score>=0.0 and Score<=100.0));

1.4 撤销或追加约束——Alter Table

1
2
3
4
5
6
7
8
9
10
11
ALTER TABLE tblname
[ADD ({colname datatype [DEFAULT {default_const|NULL}]
[col_constr {col_constr...}] | ,table_constr}
{, colname...})] // 新增列(不只是约束)
[DROP {COLUMN columnname | (columnname {, columnname...})}]
[MODIFY (columnname data-type
[DEFAULT {default_const | NULL}] [[NOT] NULL]
{, columnname...})]
[ADD CONSTRAINT constr_name]
[DROP CONSTRAINT constr_name]
[DROP PRIMARY KEY];

例: 撤消SC表的ctscore约束

1
2
Alter Table SC
DROP CONSTRAINT ctscore;

例: 在Oracle中增加新约束,需要通过修改列的定义来完成

1
2
Alter Table SC
Modify (Score float(1) constraint nctscore check (Score>=0.0 and Score<=150.0));

有的DBMS支持独立的追加约束。

1
2
Alter Table SC
Add Constraint nctscore check (Score>=0.0 and Score<=150.0));

2. SQL语言实现约束方法——断言ASSERTION

一个断言就是一个谓词表达式,它表达了希望数据库总能满足的条件;

表约束和列约束就是一些特殊的断言;

当一个断言创建后,系统将检测其有效性,并在每一次更新中测试更新是否违反该断言。

1
CREATE ASSERTION <assertion-name> CHECK <predicate>

例: 每个分行的贷款总量必须小于该分行所有账户的余额总和

1
2
3
4
5
6
create assertion sum_constraint check
(not exists (select * from branch
where (select sum(amount) from loan
where loan.branch_name = branch.branch_name)
>= (select sum(balance) from account
where account.branch_name = branch.branch_name)))

三. 利用 SQL 语言实现数据库的动态完整性

image-20220314115155077

1. 实现数据库动态完整的方法——触发器Trigger

1
2
3
4
5
6
CREATE TRIGGER trigger_name BEFORE | AFTER
{INSERT | DELETE | UPDATE [OF colname {, colname...}]}
ON tablename [REFERENCING corr_name_def {, corr_name_def...}]
[FOR EACH ROW | FOR EACH STATEMENT]
[WHEN (search_condition)]
{statement | BEGIN ATOMIC statement; {statement; ...} END}

含义: 当某一事件发生时(Before|After),对该事件产生的结果(或是每一元组,或是整个操作的所有元组),检查条件 search_condition,如果满足条件,则执行后面的程序段。条件或程序段中引用的变量可用corr_name_def 来限定。

更新前的值和更新后的值(新旧元组/Table的命名),由corr_name_def来区分:

1
2
3
4
5
6
{
OLD [ROW] [AS] old_row_corr_name
NEW [ROW] [AS] new_row_corr_name
OLD TABLE [AS] old_table_corr_name
OLD TABLE [AS] new_table_corr_name
}

例1: 设计一个触发器当进行Teacher表更新元组时,使其工资只能升不能降

1
2
3
4
5
6
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');
end;

例2: 假设student(Sid, Sname, SumCourse),SumCourse 为该同学已学习课程的门数,初始值为0,以后每选修一门都要对其增1。设计一个触发器自动完成上述功能。

1
2
3
4
5
6
7
create trigger sumc after insert on SC
referencing new row newi
for each row
begin
update student set SumCourse = SumCourse + 1
where Sid = newi.Sid;
end;

例3: 假设student(Sid, Sname, Sage, Ssex, Sclass) 中某一学生要变更其主码Sid的值,如使其原来的98030101变更为99030131,此时SC表中该同学已选课记录的Sid也需自动随其改变。设计一个触发器完成上述功能。

1
2
3
4
5
6
create trigger updSid after update of Sid on Student
referencing old oldi, new newi
for each row
begin
update SC set Sid=newi.Sid where Sid=oldi.Sid;
end;

例4: 假设student(Sid, Sname, SumCourse), 当删除某一同学Sid时,该同学的所有选课也都要删除。设计一个触发器完成上述功能。

1
2
3
4
5
6
create trigger delSid after delete on Student
referencing old oldi
for each row
begin
delete SC where Sid=oldi.Sid;
end;

例5: 假设student(Sid, Sname, SumCourse),当删除某一同学Sid时,该同学的所有选课中的Sid都要置为空值。设计一个触发器完成上述功能

1
2
3
4
5
6
create trigger delSid after delete on Student
referencing old oldi
for each row
begin
update SC set Sid = NULL where Sid=oldi.Sid;
end;

例6: 假设Dept(Did, Dname, Dean),而Dean一定是该系教师Teacher(Tid, Tname, Did, Salary)中工资最高的教师。设计一个触发器完成上述功能

1
2
3
4
5
6
7
8
create trigger upddean before update of Dean on Dept
referencing old oldi, new newi
for each row when (dean not in
select Tname from Teacher where Did=newi.Did and salary >= all
(select salary from Teacher where Did=newi.id))
begin
raise_application_error(-20003, 'invalid Dean on update');
end;

四. 数据库安全性的概念及分类

1. 数据库安全性的概念

数据库安全性:DBMS应该保证的数据库的一种特性(机制或手段),免受非法、非授权用户的使用、泄漏、更改或破坏。

涉及方面:法律伦理、公共制度/政策、安全策略等;

数据的安全级别:绝密(Top Secret)、机密(Secret)、可信(Confidential)、无分类(Unclassified);

数据库系统DBS的安全级别:物理控制、网络控制、操作系统控制、DBMS控制。

DBMS的安全机制:

  • 自主安全性机制:存取控制(Access Control)
    • 权限在用户之间传递,用户自主管理数据库安全性
  • 强制安全性机制
    • 对数据和用户强制分类,不同用户访问不同类别的数据
  • 推断控制机制
    • 防止通过公开信息/历史信息推断出其他/私密信息
  • 数据加密存储机制

2. 数据库的自主安全机制

自主安全性通过授权机制来实现。DBA处获得账户,授予该账户一定权限 依据权限操作数据库 权限转授

DBMS实现自主安全性:用户定义安全性控制规则(DCL) DBMS按照规则检查

2.1 数据库自主安全性访问规则

Access Rule ::= (S, O, t, P) ,表示:S用户对O这个访问对象,在满足P的条件下,拥有t这个权利

  • S:请求主题(用户)
  • O:访问对象(属性/字段、记录/元组、关系、数据库等不同粒度)
  • t:访问权限(创建、增、删、改、查等)
  • P:谓词(拥有权限需要满足的条件)

2.2 两种自主安全性实现方法

image-20220315194723435

存储矩阵

image-20220315195027379

问题在于不能反映条件,即谓词P

视图

视图是安全性控制的重要手段

  • 通过视图可以限制用户对关系中某些数据项的存取
  • 通过视图可将数据访问对象与谓词结合起来,限制用户对关系中某些元组的存取
  • 用户定义视图后,视图便成为一新的数据对象,参与到存储矩阵与能力表中进行描述

视图的形式可以反映出谓词P

五. 利用 SQL 语言实现数据库的自主安全性

1. SQL语言的用户与权利

数据库安全性控制是属于DCL范畴

超级用户(DBA) 账户级别(程序员用户) 关系级别(普通用户)

  • (级别一)Select:读
  • (级别二)Modify:更新
    • Insert:插入
    • Update:更新
    • Delete:删除
  • (级别三)Create:创建(表空间、模式、表、索引、视图等)
    • Create:创建
    • Alter:更新
    • Drop:删除

级别高的权利自动包含级别低的权利

2. DCL命令

2.1 授权命令

1
2
3
4
GRANT {all PRIVILEGES | privilege {,privilege...}}
ON [TABLE] tablename | viewname
TO {public | user-id {, user-id...}}
[WITH GRANT OPTION];
  • privilege 是权利:SELECT | INSERT | UPDATE | DELETE | ALL PRIVILEDGES
  • public 所有有效账户授权,user-id 某一个用户账户
  • WITH GRANT OPTION:允许被授权者传播这些权利

例:

1
2
Grant All Priviledges ON Employee TO Emp2001;
Grant SELECT ON EmpV2 TO Emp5001;

2.2 收回授权命令

1
2
3
REVOKE {all privilEges | priv {, priv...}}
ON tablename | viewname
FROM {public | user {, user...}};

六. 安全性控制的其他简介

1. 自主安全性的授权过程及其问题

授权过程

  • 第一步:DBA创建DB,为每一个用户创建一个账户
  • 第二步:DBA授予某用户账户级别的权利
  • 第三步:具有账户级别的用户可以创建基本表或视图,也自动成为该表/视图的属主账户,拥有该表或该视图的所有访问权利
  • 第四步:拥有属主账户的用户可以将一部分权利授予另外的用户,该用户也可将权利进一步授权给其他的用户

授权的传播范围

  • 水平传播数量:是授权者的再授权用户数目(广度)
  • 垂直传播数量:被授权者再传播给另一个被授权者(深度)

2. 强制安全性机制

数据对象和用户进行安全性分级

绝密(Top Secret)、机密(Secret)、可信(Confidential)、无分类(Unclassified)

  • 用户 S,不能取数据对象 O,除非 Level(S)>=Level(O)
  • 用户 S,不能数据对象 O, 除非 Level(S)<=Level(O)

通过扩展关系模式来实现强制安全性机制(多级关系)

image-20220315202716341