这一章的内容主要包括一些完整性约束,比如实体完整性,参照完整性,用户定义完整性,它们怎么建立,怎么删除,怎么用,还有对完整性约束的命名子句,断言和触发器的操作,都为概念性内容,都很简单
实体完整性
定义
实体完整性用primary key 来定义,建立主码,分为表级完整性约束和列级完整性约束
列级完整性约束:建表时在主码后面加 primary key
表级完整性约束:建表时在所有属性后加:primary key (属性名,属性名...)
其中primary key 为单个属性时两种约束都可,为多个属性的组合时只能用表级完整性约束
检查和违约处理
主码要求唯一+不空
检查不空的要求容易实现,主要是检查唯一性
基本方法:全表扫描查看是否非空,耗时;
改进:DBMS一般给主码自动建立索引,例如用B+树存主码,实现快速查找
若插入或修改时发现主码不唯一或者非空,则拒绝插入或修改
参照完整性
定义
主要是为了维护外码
建立方法: 建表时在所有属性后加:foreign key (本表属性名) reference 外表(外表属性名)
参照完整性检查和违约处理
任何对涉及外码的属性的操作,导致外码前后逻辑不一致,或与现实理解相违背的都会破坏参照完整性
处理方法
系统默认:拒绝执行(no action)
级联操作:当参照表发生更新或删除导致违背参照完整性时,被参照表自动进行相应的更新或删除操作从而达到参照完整性的要求(cascade)
设置为空值:要根据实际情况看看能不能取空值(set-nul)
相关句式这样写:
foreign key (Sno) references Student(Sno)
on delete cascade
on update cascade;
foreign key (Cno) references Course(Cno)
on delete no action
on update set-null;
用户定义的完整性
定义
就是用户根据实际情况对一些属性进行约束
比如数据库中名字这个属性不能为空值,就可以在后面加 not null ,身份证号唯一,在后面加unique
要一个列值满足一个条件表达式,用check(表达式)
属性后面加上not null unique 这俩,也就差不多能当候选码了
相关句式:
Sno char(9) not null,
Dname char(9) unique not null,
Ssex char(2) check(Ssex in ('男','女'));
当然check里面可以是更复杂的表达式,子句
check可放在属性后头,也可放在所有属性最下面,就和primary key 一样
违约处理
拒绝执行
约束元组
前面都是对列值的约束,可以通过用户自定义完整性来对行值进行约束
举例:男生名字不能以Ms.打头
check(Ssex='女' or Sname not like 'Ms.%') //性别为女不然名字前就不是Ms.
完整性约束命名子句
定义
对完整性约束起个名字,这样想增删改完整性,直接根据名字改
句式
constraint <完整性约束名> <完整性约束条件>
Sname char(20) constraint C2 not null, //(这个约束条件也可以是check子句)
也可在所有属性最下面加,比如:
constraint C3 primary key(Sno)
用途
对完整性约束的增删改
alter table student drop constraint C1;
alter table student add constraint C2 check(...)
完整性约束不能直接改,可以先删在加一个新的
断言
定义
目的也就是为了搞个单独的句子,加一个约束,要求所有操作必须满足这个断言
创建断言
create assertion <断言名> <check 子句>
删除断言
drop assertion <断言名>
触发器
定义
create trigger <触发器名>
{before|after}<触发事件> on <表名>
references new|old row as <变量>
for each {row|statement}
[when<触发条件>] <触发动作体>
作用
能够实现由主键和外键所不能保证的复杂的参照完整性和数据的一致性,比如要求:修改之后的列值不能比修改之前的列值多20,这种的,用触发器里的oldrow和newrow来控制
跟踪变化,级联运行,运行一个操作之后,系统自动运行预期的下一个操作
删除触发器
drop trigger <触发器名> on <表名>