SQL语言与数据库完整性和安全性

一、数据库完整性的概念及分类

1.1 什么是数据库完整性

  • 数据库完整性(DB Integrity):是指DBMS应保证的DB的一种特性--在任何情况下的正确性、有效性和一致性
    • 广义完整性:语义完整性、并发控制、安全控制、DB故障恢复等
    • 狭义的完整性:专指语义完整性,DBMS通常有专门的完整性管理机制与程序来处理语义完整性问题。
  • 完整性涉及到
    • 关系模型中的完整性要求
      • 实体完整性
      • 参照完整性
      • 用户自定义完整性

1.2 为什么会产生完整性问题

  • 不正当的数据库操作,如输入错误、操作失误、程序处理失误等
  • 数据库完整性管理的作用
    • 防止和避免数据库中不合理数据的出现
    • DBMS应尽可能地自动防止DB中语义不合理现象

1.3 怎样保证数据库的完整性

  • DBMS允许用户定义一些完整性约束规则(用SQL-DDL来定义)
  • 当有DB更新操作时,DBMS自动按照完整性约束条件进行检查,以确保更新操作符合语义完整性

  • 完整性约束条件(或称完整性约束规则等)的一般形式
  • Integrity Constraint ::=(O,P,A,R)
    • O:数据集合:约束的对象
      • 列、多列(元组)、元组集合
    • P:谓词条件,什么样的约束
    • A:触发条件:什么时候检查
    • R:响应动作:不满足时怎么办

1.4 完整性约束的分类

1.4.1 按约束对象分类

  • 域完整性约束条件
    • 施加于某一列上,对给定列上所要更新的某一候选值是否可以接受进行约束条件判断,这是孤立的
  • 关系完整性约束条件
    • 施加于关系/table上,对给定table上所要更新的某一候选元组是否可以接受进行约束条件判断,或是对一个关系中的若干元组和另一个关系中的若干元组间的联系是否可以接受进行约束条件判断

1.4.2 按约束来源分类

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

1.4.3 按约束状态分类

  • 静态约束
    • 要求DB在任一时候均满足的约束;例如Sage在任何时候都应该满足大于0而小于150(假定人活最大年龄是150)
  • 动态约束
    • 要求DB从一状态变为另一状态时应满足的约束;例如工资只能升,不能降

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

2.1 SQL语言支持如下几种约束

  • 静态约束
    • 列完整性——域完整性约束
    • 表完整性——关系完整性约束
  • 动态约束
    • 触发器

2.2 SQL语言实现约束的方法-Create Table

  • create table有三种功能:定义关系模式、定义完整性约束、和定义物理存储特性
  • 定义完整性约束条件
    • 列完整性
    • 表完整性
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}
...});
  • col_constr列约束:一种域约束类型,对单一值进行约束
{not null |    // 列值非空
    [constraint constraintname]    // 为约束命名,便于以后撤销
        { unique    // 列值唯一
          | primary key    // 列为主键
          | check (search_cond)    // 列值满足条件,条件只能使用列当前值
          | references tablename [(colname)] [on delete {cascade|set null}]}} // 引用另一个表tablename的列colname的值,如有on delete cascade 或on delete set null语句,则删除被引用表的某列值v时,要将本表该列值为v的记录删除或列值更新为null;缺省为无操作
  • Col_constr列约束:只能应用在单一列上,其后面的约束如unqiue,primary key及search_cond只能是单一列唯一、单一列为主键、单一列相关
  • 例1
# 假定Ssex只能取{男,女}, 1=<Sage<=150, D#是外键
create table student(
`S#` 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),
`D#` char(2) references Dept(D#) on delete cascade,
Sclass char(6));    

//假定每门课学分最多5分,最少0分
create table Course(
C# char(3),
Cname char(12),
Chours integer,
Credit float(1) constraint ctcredit check (Credit >= 0.0 and Credit <= 5.0),
T# char(3) references Teacher(T#) on delete cascade);

  • table_constr表约束:是应用在关系上,即应用在关系上,即对关系的多列或元组进行约束,列约束是其特例
  • 一种关系约束类型,对多列或元组的值进行约束
[constraint constraintname]    // 为约束命名,便于以后撤销
    {unique (colname {, colname...})    //几列值组合在一起是唯一
    | primary key (colname {, colname...})    //几列值联合为主键
    | check(search_condition)    // 元组多列值共同满足条件,条件中只能使用同一元组的不同列当前值
    | foreing key(colname {,colname...})
    references tablename [(colname {, colname...})]
    [on delete cascade]    // 引用另一表tablename的若干列的值作为外键
}
  • check中的条件可以是select-from-where内任何where后的语句,包含子查询
  • create table中定义的表约束或列约束可以在以后根据需要进行撤销或追加。撤销或追加约束的语句是alter table(不同的系统可能有差异)
alter table tablename
[add ({colname datatype [default {default_const|null}]
        [col_constr{col_constr}]|,table_constr}
    {, colname....})]
[drop {column culumnname|(columname{,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约束(由此可见,未命名的约束是不能撤销的)
alter table SC
drop constraint ctscore;
  • 例:若要再对SC表的score进行约束,比如分数在0-150之间,则可新增加一个约束。在Oracle中增加新约束,需要通过修改列的定义来完成
alter table SC
modify (Score float(1) constraint nctscore check (Score>=0.0 and Score<=150.0));

2.3 SQL语言实现约束的方法-断言

2.3.1 断言ASSERTION

  • 一个断言就是一个谓词表达式,它表达了希望数据库总能满足的条件
  • 表约束和列约束就是一些特殊的断言
  • SQL还提供了复杂条件表达的断言。其语法形式为:
create assertion <assertion-name> check <predicate>
  • 当一个断言创建后,系统将检测其有效性,并在每一次更新中测试更新是否违反该断言
  • 断言测试增加了数据库维护的负担,要小心使用复杂的断言
  • 例:每笔贷款,要求至少一位借款者账户中存有最低数目的余额,例如1000元
create assertion balance_constraint check
(not exists (
    select * from loan
    where not exists (
        select * from borrower, depositor, account
        where loan.loan_number = borrower.loan_number
            and borrow.customer_name = depositor.customer_name
            and depositor.account_number = account.account_number
            and account.balance >= 1000)));

  • 例:每个分行的贷款总量必须小于该分行所有账户的余额总和
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语言实现数据库的动态完整性

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

  • create table中的表约束和列约束基本上都是静态的约束,也基本上都是对单一列或单一元组的约束(尽管有参照完整性),为实现动态约束以及多个元组之间的完整性约束,就需要触发器技术Tigger
  • Tigger是一种过程完整性约束(相比之下,create table中定义的都是非过程性约束),是一段程序,该程序可以在特定的时刻被自动触发执行,比如在一次更新操作之前执行,或在更新之后执行。
  • 基本语法:
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};
  • 触发器Trigger意义:当某一个事件发生时(before|after),对该事件产生的结果(或是每一元组,或是整个操作的所有元组),检查条件search_condition,如果满足条件,则执行后面的程序段。条件或程序段中引用的变量可用corr_name_def来限定
  • 事件:before|after {insert | delete | update ...}
    • 当一个事件(insert,delete,或update)发生之前before或发生之后after触发
    • 操作发生,执行触发器操作需处理两组值;更新前的值和更新后的值,这个值由corr_name_def的使用来区分

  • corr_name_def的定义
{ old [row] [as] old_row_corr_name    // 更新前的旧元组命别名为
| new [row] [as] new_row_corr_name    // 更新后的新元组命别名为
old [row] [as] old_row_corr_name    // 更新前的旧元组命别名为
| new [row] [as] new_row_corr_name    // 更新后的新元组命别名为
}
  • corr_name_def将在检测条件或后面的动作程序中被引用处理
  • 例1:设计一个触发器当进行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');  // 此条语句是ORcale的错误处理函数
    end;
  • 例2:假设student(S#, Sname, SumCourse), SumCourse为该同学已学习课程的门数,初始值为0,以后每选修一门都要对其增1 。设计一个触发器自动完成上 述功能。
create trigger sumc after insert on sc
    refercing new row newi
    for each row
        begin
            update student set SumCourse = SumCourse + 1
            where S#=:newi.S#;
        end;
  • 例3:假设student(S#, Sname, Sage, Ssex, Sclass)中某一学生要变更其主码S#的值,如使其原来的98030101变更为99030131, 此时sc表中该同学已选课记录 的S#也需自动随其改变。设计一个触发器完成上述功能
create trigger updS# after update of S# on student
referencing old oldi, new newi
for each row
begin
update sc set S#=newi.S# where S#=:old.S#;
end;
  • 例4:假设student(S#, Sname, SumCourse), 当删除某一同学S#时,该同学的所 有选课也都要删除。设计一个触发器完成上述功能
create trigger delS# after delete on Student
referencing old oldi
for each row
begin
delete sc where S#=:oldi.S#;
end;
  • 例5:假设student(S#, Sname, SumCourse), 当删除某一同学S#时,该同学的所 有选课中的S#都要置为空值。设计一个触发器完成上述功能
create trigger delS# after delete on Student
referencing old oldi
for each row
begin
    update sc set S# = NULL where S# = :oldi.S#;
end;
  • 例六:假设Dept(D#, Dname, Dean), 而Dean一定是该系教师Teacher(T#, Tname, D#, Salary)中工资最高的教师。设计一个触发器完成上述功能
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 D#=:newi.D#
and salary >=all(select salary from Teacher where D#=:newi.D#))
begin 
raise_application_error(-20003,'invalid Dean on update');
end;

三、数据库安全性的概念和分类

3.1 数据库安全性的概念

  • 数据库安全性是指DBMS应该保证的数据库的一种特性(机制或手段):免受非法、非法授权用户的使用、泄漏、更改或破坏
  • 数据库安全性管理涉及到许多方面
    • 社会法律及伦理方面:私人信息收到保护,未授权人员访问私人信息违法
    • 公共政策/制度方面:例如:政府或组织的信息公开或非公开制度
    • 安全策略:政府、企业或组织所实施的安全性策略,如集中管理和分散管理,需者方知策略(也称最少特权策略)
    • 数据的安全级别:绝密(Top Secret),机密(Secret),可信(Confidential)和无分类(Unclassified)
    • 数据库系统DBS的安全级别:物理控制、网络控制、操作系统控制、DBMS控制

3.2 数据库安全性的分类

  • 自主安全性机制:存取控制(Access Control)
    • 通过限制在用户之间的传递,使用户自主管理数据库安全性
  • 强制安全性机制
    • 通过对数据和用户强制分类,使得不同类别用户能够访问不同类别的数据
  • 推断控制机制
    • 防止通过历史信息,推断出不该被其知道的信息
    • 防止通过公开信息(通常是一些聚集信息)推断出私密信息(个体信息),通常在一些由个体数据构成的公共数据库中此问题尤为重要
  • 数据加密存储机制
    • 通过加密、解密保护数据,密钥、加密/解密方法与传输

3.3 数据库管理员的责任与义务

  • 熟悉熟悉相关的法规、政策,协助组织的决策者制定好相关的安全策略
  • 规划好安全控制保障措施,例如,系统安全级别、不同级别上的安全控制措施,对安全遭破坏的响应
  • 划分好数据的安全级别以及用户的安全级别
  • 实施安全性控制:DBMS专门提供一个DBA账户,该账户是一个超级用户 或称系统用户。DBA利用该账户的特权可以进行用户账户的创建以及权限授 予和撤消、安全级别控制调整等

3.4 数据库自主安全性机制

3.4.1 数据库自主安全性

  • 自主安全性机制
    • 通常情况下,自主安全性是通过授权机制来实现的
    • 用户在使用数据库前必须由DBA处获得一个账户,并由DBA授予该账户一定的权限,该账户的用户依据其所拥有的权限对数据库进行操作;同时,该账户用户也可将其所拥有的权利转授给其他的用户,由此可以实现权限在用户之间的传播和控制
      • 授权者:决定用户权利的人
      • 授权:授予用户访问的权利

3.4.2 DBMS怎样实现数据库自主安全性

  • DBMS允许用户定义一些安全性控制规则(用SQL-DCL来定义)
  • 当有DB访问操作时,DBMS自动按照安全性控制规则进行检查,检查通过则允许访问,不通过则不允许访问

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

  • DBMS将权利和用户(账户)结合在一起,形成一个访问规则表,依据该规则表可以实现对数据库的安全性控制
  • AccessRule ::= (S,O,t.P)
    • S:请求主体(用户)
    • O:访问对象
    • t:访问权利
    • P:谓词
  • {AccessRule}通常存放在数据字典或称系统目录中,构成了所有用户对DB的访问权利
  • 用户多时,可以按用户组建立访问规则
  • 访问对象可大可小(目标粒度Object granularity):属性/字段、记录/元组、关系、数据库
  • 权利:包括创建、增、删、改、查等
  • 谓词:拥有权利需满足的条件

3.4.4 自主安全性的实现方式一:存储矩阵

3.4.5 自主安全性的实现方式二:视图

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

四、利用SQL语言实现数据库自主安全性

4.1 SQL语言的用户与权利

  • SQL语言包含了DDL、DML和DCL。数据库安全性控制是属于DCL范畴
  • 授权机制——自主安全性;视图的运用
  • 关系级别(普通用户)\leftarrow账户级别(程序员用户)\leftarrow超级用户(DBA)
    • (级别1)select:读(读DB\Talbe\Tecord\Attribute\...)
    • (级别2)Modify:更新
      • Insert:插入插入新元组,...)
      • Update:更新(更新元组中的某些值,...)
      • Delete:删除(删除元组,...)
    • (级别3)Create:创建(创建表空间、模式、表、索引、视图等)
      • create:创建
      • alter:更新
      • drop:删除
  • 级别搞的权利自动包含级别低的权利。如某人拥有更新的权利,它也自动拥有读的权利。在有些DBMS中,将级别3的权利称为账户级别的权利,而将级别1和2称为关系级别权利

4.2 SQL-DCL的命令及其应用

  • 授权命令
grant {all privileges|privilege{,privilege...}}
on [table] tablename|viewname
to {public|user-id {,user-id...}}
[with grant option];
  • user-id,某一个用户账户,由DBA创建的合法账户
  • public,允许所有有效用户使用授权的权利
  • privilege是下面的权利
    • select | insert | update | delete | all priviledges
  • with grant option选项是允许被授权者传播这些权利
  • 收回授权命令
revoke {all privileges|priv {,priv...}} on tablename|viewname
from {public|user{,user...}};

4.3 安全性控制的其他简介

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

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

  • 注意授权的传播范围
    • 传播范围包括两个方面:水平传播数量和垂直传播数量
      • 水平传播数量是授权者的再授权用户数目(树的广度)
      • 垂直传播数量是授权者传播给被授权者,在被传播给另一个被授权者,...传播的深度(树的深度)
    • 有些系统提供了传播范围控制,有些系统并没有提供,SQL标准中也并没有限制。

  • 当一个用户的权利被收回时,通过其传播给其他用户的权利也将被收回
  • 如果一个用户从多个用户处获得了授权,则当其中某一个用户收回授权时,该用户可能仍包邮权利。

4.4 强制安全性机制

4.4.1 强制安全性机制

  • 强制安全性通过对数据对象进行安全性分级
    • 绝密(Top Secret),机密(Secret),可信(Confidential)和无分类(Unclassified)
  • 同时对用户也进行上述安全性分级
  • 从而强制实现不同级别用户访问不同级别数据的一种机制

4.4.2 访问规则

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

4.4.3 强制安全性机制的实现

  • DBMS引入强制安全性机制,可以通过扩展关系模式来实现
    • 关系模式:R(A1:D1,A2:D2,...,An:Dn)
    • 对属性和元组引入安全性分级特性或称分类特性
      • R(A1:D1,C1,A2,D2,C2,...,An:Dn,Cn,TC)
      • 其中C1,C2,...,Cn分别为属性D1,D2,...,Dn的安全分类特性;TC为元组的分类特性
    • 这样关系中的每个元组,都将扩展为带有安全分级的元组,例如

  • 强制安全性机制使得关系形成为多级关系(不同级别用户所能看到的关系的子集),也出现多重实例、多级关系完整性等许多新的问题或新的处理技巧,在使用中需要注意仔细研究

猜你喜欢

转载自blog.csdn.net/qq_38689352/article/details/111057285