数据库复习3——数据库完整性

数据库复习


CH5 完整性

5.1 完整性约束

数据库完整性是指数据库中数据在逻辑上的一致性、正确性、有效性和相容性,那么完整性约束就是指用户插入、修改和删除操作时,DBMS为了保证数据库逻辑上的一致性、正确性、有效性和相容性所必需要检查的约束条件

C.J.Date在《An Introduction to Database Systems》一书中描述了四种完整性约束:

  • 类型约束
  • 属性约束
  • 关系变量约束
  • 数据库约束

C.J.Date提出的理论多半是建立在他自创的Tutorial D这个概念型数据库操作语言上的,下面的描述也是基于Tutorial D,注意不要和SQL混淆

(1)类型约束

类型约束是关于自定义类型的种类(或就是数域)以及值大小的约束,例如我们自定类型weight是实数类型且要求weight必须大于0,那么用Tutorial D定义一个类型约束如下:

TYPE weight POSSREP(RATIONAL) CONSTRAINT the_weight(weight) > 0.0;

POSSREP是possible representation(可能的表达方式),RATIONAL是有理数,the_加weight(前面提到过这是C.J.Date提出的对类型的操作符号,表示取值)weight作用于weight表示取值

(2)属性约束

属性约束就是定义关系时定义属性的类型产生的隐式约束,Tutorial D定义一个关系如下:

VAR S BASE RELATION(S# S#, status integer, city char);

比如上例的status就需要隐式遵守类型integer的类型约束

(3)关系变量约束

关系变量约束是对关系中元组的约束,如限定在伦敦的供应商状态一定是20:

Constraint sc1 is_empty(S where city = ‘London‘ and status ~= 20);

关系变量约束总是立即检查的

(4)数据库约束

关系变量约束是针对单个关系变量内部属性的约束(可以把关系变量就理解为关系/表),若约束涉及多个关系变量,则称之为数据库约束

如下的数据库约束,限定零件商的个数必须等于供应表中零件商的个数:

Constraint dbc1 count(SP(p#)) = count(P(p#));

(5)约束设计的黄金准则(Golden Rule)

关于Golden Rule,C.J.Date在这里想要表达的是我们定义的所有完整性约束都称之为内部约束,用户和DBMS都很清楚,比如体重必须大于0

然而我们设计的系统还有很多其他的外部约束,比如说我的体重是69.5,那么可以插入一个元组(jcguo, 69.5),但是插入(jcguo, 100.5)说我是个大胖子DBMS也是允许的,但这违反了现实世界的约束

这届涉及到之前在完整性定义中包括的正确性,C.J.Date认为这部分的完整性应该由用户或者说DBA在数据库外部限定,而不是交给DBMS

5.2 键Key

数据库中可以定义一种特殊的完整性约束——键(key,或者有时也翻译为码,我叫键比较顺口)

(1)各种键的定义

我们先来弄清楚各种键的定义:

  • super key:超键,在关系中能够唯一标识元组的属性集
  • candidate key:候选键(一般叫候选码),不含有多余属性/不可规约超键
  • primary key:主键,用户选做唯一表识元组的候选键,主键不能为null
  • alternate key:可选键,候选键中除了主键以外,没有被用户选中的候选键
  • foreign key:外键,是依赖于其他关系用于保证数据库逻辑完整性的约束

前四个key都很好理解,下面着重理解一下外键

(2)外键

关系R1声明在属性a1上创建外键FK,那么有:

  • 这个外键FK必须reference(引用or以来)于另一个关系R2的候选键CK(一般reference另一个关系的主键,设CK创建于属性a2上)
  • 这个reference的作用就是保证R1中属性a1中出现的值全部都在R2的a2中出现(完整性约束)

注意,外键FK并不要求R2中属性a2(CK)中出现的值都必须在R1中属性a1中出现,只是说单方面的约束:一旦在FK中出现则必须在CK中出现

外键还有另一个最重要的特性:referential action(关联动作),关联动作是一个隐式的特殊的触发器(每当满足出发条件时都会出发的动作集合)

下面在讲SQL完整性时会详细阐述SQL所支持的关联动作

5.3 SQL完整性

再次强调之前我们复习的所有完整性都是抽象性的概念,需要理解,那么这一小节SQL完整性则需要记忆了

(1)域约束

域约束(Domain Constraints)是SQL中对属性取值范围的约束,SQL声明域约束是在create table时完成的,支持带名称的显式约束声明以及不带名称的便捷约束声明两种方式:

create table Student(
    S# char(10),
    name char(20),
    gender char(1),
    constraint gc check (gender in (‘F‘, ‘M‘))
);

和下面等价:

create table Student(
    S# char(10),
    name char(20),
    gender char(1) check (gender in (‘F‘, ‘M‘))
);

check从句中可以使用常用的比较关系操作符号,也可以使用in构造复合语句

给约束命名是为了某些特殊情况我们需要对约束进行修改,见我另外一篇博文:

另外SQL支持对已声明的table添加约束,使用alter table语句,本课程暂不要求

(2)主键

SQL主键声明也是在create table时声明的,声明主键也有两种方式(显式和便捷式,显式主键不需要名字,因为一个关系/表只能有一个主键):

create table Student(
    S# char(10),
    name char(20),
    gender char(1) check (gender in (‘F‘, ‘M‘)),
    primary key (S#)
);

等价于:

create table Student(
    S# char(10) primary key,
    name char(20),
    gender char(1) check (gender in (‘F‘, ‘M‘))
);

需要注意的是主键不能为空,不能插入一条不包含主键/主键为null的元组

primary key也可以作用于多个属性,如同前面概念讲解中所提到的,如何设计依需求而定

(3)unique

SQL中实现候选码使用unique约束,一个关系可以有多条unique约束

这句话翻译自老师ppt,个人觉得需要补充:

  • SQL中淡化了candidate key的概念
  • unique约束不仅可以实现候选码,也可以实现超码,也就是它没有不可约的限制

声明uniqle约束和主键类似,举例略

(4)外键

Foreign key之前留了个坑,这里直接举例吧:

create table Dept(
    D# char(3) primary key,
    name char(20),
    type char(20) check (type in (‘engineering‘, ‘science‘, ‘business‘))
);

先创建了一个table Dept是系的关系,它的主键是D#,再创建一个Student表,它的属性D#上声明了一个引用Dept(D#)的外键:

create table Student(
    S# char(10) primary key,
    name char(20),
    gender char(1) check (gender in (‘F‘, ‘M‘)),
    D# char(3) foreign key references Dept(D#)
);

上面的声明等价于:

create table Student(
    S# char(10) primary key,
    name char(20),
    gender char(1) check (gender in (‘F‘, ‘M‘)),
    D# char(3),
    contraint dfk foreign key references Dept(D#)
);

这里外键的约束就是限制学生表里的D#必须在系表里的D#中出现,那么很容易想到一个问题:如果USTC新任校长万老大把11系拆了,也就是系表里把D#为’011’的元组删除了的话,那我们11系的学生在Student表里的tuples不就不满足外键约束了吗

这时候就需要引入关联动作,关联动作分为级联(Cascade)动作和设置(Set)动作

1.级联动作

级联动作就是一系列的主键-外键-主键-外键-…约束引用链条的后端的某个主键delete或update,会产生(自动的,触发器)沿引用链条从后往前的一系列外键的delete或update操作

例如我们声明一个D#的删除级联,即:

create table Student(
    S# char(10) primary key,
    name char(20),
    gender char(1) check (gender in (‘F‘, ‘M‘)),
    D# char(3) foreign key references Dept(D#) on delete cascade
);

此时删除11系,那么根据级联动作定义,所有11系的学生都被删除,因为Student表通过外键引用了Dept表的主键

再假设Dept表引用了一个学校编号U#的外键,它是一个University表的主键,此时构成了一个引用链条,若这个University表删除了USTC的条目,那么根据级联动作定义USTC的11系,11系的学生都将被自动删除

级联动作也可以是on update cascade,比如11系改系别号为1系了,那么11系的学生能够自动的把D#改成‘001’

DBMS处理级联动作是按事务来处理的,若在引用链条中某一个部分的级联动作违反了其他的完整性约束,那么整个修改动作都会被回滚(事务的概念),即修改失败

ppt中写道:

Referential integrity is only checked at the end of a transaction

–– Intermediate steps are allowed to violate referential integrity provided later steps remove the violation, otherwise it would be impossible to create some database states, e.g. insert two tuples whose foreign keys point to each other

很不幸的是在实验中我发现这条规则MySQL适用但Oracle并不适用(至少在PL/SQL中)

SQL支持一个外键同时有一个删除级联和一个更新级联

2.设置动作

设置动作比较好理解:

  • on delete set null
  • on delete set default

5.4 断言和触发器

(1)断言

SQL还支持使用断言(Assertion)在关系外部定义数据库必须满足的条件,语法为:

create assertion <assertion_name> check <predicate>;

Assertion有点类似于C.J.Date定义的数据库约束,可以针对单表或多表

ppt中一个复杂的例子,限定每个部门的工资总和必须小于d1部门的工资总和:

create assertion sac check(
    not exists(
        select * from EMP e2
        where (select sum(sal) from EMP e1 where e1.d# = e2.d#)
            >= (select sum(sal) from EMP where d# = ‘d1‘)
    )
);

PS:我咋觉得第一个where后面要加d# ~= ‘d1‘ and呢?

(2)触发器

触发器定义了数据库状态改变(元组修改)时需要自动执行的一系列动作,定义触发器包括两个要点:

  • 触发条件
  • 执行动作

触发器还有几个重要属性:

  • 事前触发或事后触发
  • 行触发还是整体触发

事前触发或事后触发比较好理解,行触发还是整体触发是指的是一条update或delete时若涉及多个元组的修改,是整体触发一次还是每个元组都触发一次

还是举例说明,下面是我在Oracle上创建的行触发器:

create or replace trigger countStud
after delete or insert or update on Stud
for each row
begin
      update Dept set S_count =  S_count+1 where D# = :new.D#;
      update Dept set S_count =  S_count-1 where D# = :old.D#;
end;

这是一个用来统计系里人数的触发器(或者说叫做保证系里人数完整性的触发器),分点说明:

  • after delete or insert or update on Stud指定了触发器的条件和触发时机:当Stud表有删除、插入或更新操作之后触发
  • for each row声明这是一个行触发器,按行触发
  • begin和end包体里指定了触发器的动作

至于其中的:new和是:old保留变量,对应删除、插入或更新三个操作他们有如下含义:

含义 insert update delete
:new 新插入的元组 更新后的元组 null
:old null 更新前的元组 删除的元组

时间: 2024-08-04 13:45:31

数据库复习3——数据库完整性的相关文章

数据库复习1——数据库体系结构和关系系统

数据库复习 CH2 数据库体系结构 2.1 数据库体系结构层次 数据库体系结构可以分成3个层次: 外部层次 概念层次 内部层次 外部层次是指每个用户用不同的高级语言来访问数据库所面对的接口,概念层次数据库信息的表示以及模的式定义(包括安全性和完整性约束等等),而内部层次就是的存储表示(非物理记录也非机器相关),数据库的设计需要保证这三个层次之间的独立性: 概念层和内部层之间物理数据的独立性 外部层和概念层之间逻辑数据的独立性 2.2 DBA和DBMS DBA(数据库管理员)必须很好的了解企业的数

数据库复习之数据库系统概述

数据库是数据管理的最新技术,是计算机科学的重要分支.从联机事务处理(On-Line Transaction Processing,OLTP)到联机肥西处理(On-Line Analysis Processing,OLAP),从一般企业管理到计算机辅助设计与制造(CAD/CAM).计算机集成制造系统(CIMS).电子政务(e-Convernment).电子商务(e-Commerce)地理信息系统(GIS)等等. 数据.数据库.数据库管理系统和数据库系统是与数据库技术密切相关的4个基本概念.   数

数据库复习5——安全性

数据库复习 CH7 安全性 7.1 数据库安全性介绍 如果说完整性是针对授权用户的数据库保护措施,那么安全性就是针对非授权用户的数据库保护措施 安全性问题涉及的层面很多,非法用户可以从以下各层面对数据库的窃取或篡改: 层面 窃取或篡改行为 应对措施 数据库系统 获取高级用户数据库权限 身份验证,权限和可获取数据对等 操作系统 获取操作系统root权限想干啥就能干啥,不仅仅限于对数据库的操作了 提升操作系统安全级别 网络 通过网络窃听和身份伪装也能窃取线上机密数据 身份验证和加密传输 物理 物理上

数据库复习2——SQL基础

数据库复习 CH4 SQL SQL(Structured Query Language,结构化查询语言)是通用的关系数据库系统操作语言,下面从几个方面来复习SQL基础 4.1 DDL SQL语句可根据其操作性质分成三类: DDL(Data Definition Language) DCL(Data Constraint Language) DML(Data Manipulation Language) DCL完成完整性和安全性的约束,也可以看作从属于DDL,下面介绍DCL除外的DDL部分SQL语

数据库复习7——恢复

数据库复习 CH14 恢复 13.1 恢复的概念 数据库系统中恢复是指让数据库从发生某些"失败"后的不一致的状态恢复到正常的一致状态的行为,恢复的基础是冗余(物理上冗余,非逻辑上) 这些失败包括了: 事务失败:包括逻辑错误(事务不满足某些条件不能执行)和系统错误(DBMS强制终止事务,如事务发生死锁) 系统崩溃:断电.物理硬件损坏.软件系统(如OS)崩溃,本章假设系统崩溃不会改变非易失存储器 磁盘失败:磁盘存储发生错误,本章假设可利用检查和监测磁盘失败 大体上,恢复策略分成两个步骤:

数据库复习10——PL/SQL

数据库复习 CH10 PL/SQL 10.1 PL/SQL简介 PL/SQL是Oracle对SQL的过程化的扩展,PL/SQL可以实现SQL相关的过程化程序,并且能够以存储过程和函数的方式让一段SQL业务逻辑驻留在SQL服务器中,以便减少客户机计算任务并减少网络I/O 10.2 PL/SQL编程基础 (1)简介 PL/SQL编程框架为: DECLARE <Variable List> BEGIN <Extented SQL Execution> EXCEPTION <Exce

数据库复习6——事务

数据库复习 CH13 事务 13.1 事务的概念 事务是作为单个逻辑工作单元执行的一系列数据库操作,这些操作可能会修改多个表中的多个元组 事务正常执行的结构是: begin; SQL execution 1 SQL execution 2 ... SQL execution N commit; begin标志开始一个事务,多个SQL语句就是事务逻辑工作单元,commit(提交)是结束当前事务并提交事务内数据变更,让其生效 数据库一致性在事务上表现的比较特殊,具体来说:事务执行的过程中可以让数据库

数据库复习整理

1.关系模型的三类完整性规则:实体完整性,参照完整性,用户定义的完整性规则. 2.SQL server 默认带有四个系统数据库: master:存储系统级信息,登录账户信息,配置参数等,model:创建所有数据库模板,msdb:用于计划警报和作业,tempdb:保存临时表和临时存储过程. 3.主要数据文件 mdf,次要数据文件 ldf,事务日志文件 ldf. 4.子查询:使用in关键字 select * from student where claid in(select claid from

数据库复习4——视图

数据库复习 CH6 视图 6.1 视图的概念 视图是从一个或多个表(或视图)导出的虚表,DBMS仅在数据字典中存放视图的定义,而视图的数据仍然实际存储于导出它的基表中 Tutorial D中定义视图的基本语句如下: VAR <view_name> VIEW (<relational_condition>) {<property_list>}; 那么视图有什么作用呢? 为hidden data提供安全性,即屏蔽某些不希望外界用户看到的机密数据 提供一种简写的方式,有了视图