主动(active)元素是一个表达式或语句,只需编写一次,存储在数据库中,然后在适当的时间被执行。
关系之间的约束称为“断言”
外键约束声明
SQL可将关系的一个属性或属性组声明为外键,该外键引用另一个关系(也可以是同一个关系)的属性(组)
注意:被引用的另一个关系的属性在它所在的关系中,必须被声明为unique或pk
两种方式
presC# int references movieExec(cert#)
foreign key (presC#) references movieExec(cer#)
也可以是属性名列表
注意:presC#可以有NULL,这并不要求cert#中也要有null
维护引用完整性
DBMS会阻止在声明了外键约束的关系上的违法修改
但对于在被引用关系上的违法修改,设计者可在下面上个选项中进行选择
1.缺省原则(default):拒绝违法更新
2.级联原则(cascade):被引用属性(组)的改变被仿造到外键上(A引用B,B删A删,B改A改)
3.置空值原则(set null):当在被引用的关系上的更新影响外键值时,后者被改为空值
这些选择可独立地选择删除和修改,同外键一起声明
//presC#是关系studio中的属性
presC# int references movieExec(cert#)
on delete set null
on update cascade
//删除时置空,修改时级联
补充:违反引用完整性的元组称为悬浮元组(外键连接运算时连不上)
延迟约束检查
若要往studio中插入一个具有一个新的presC#的元组的话,必须要先去movieExec中插入具有对应的cert#的元组
但当循环约束发生时,先插入哪个都不行
要将两个插入操作组成一个单一的事务,并通知DBMS不要检查其约束,直到整个事务完成执行并要提交为止
任何约束的声明后面都可以跟上
1.deferrable:约束检查将推迟到当前事务完成是进行
2.not deferrable:缺省值,每执行一条可能违反外键约束的更新操作,都会进行检查
deferrable的后面可以更上:
1.initially deferred:检查仅被推迟到事务提交前执行
2.initially immediate:检查在每个语句后立刻被执行
DEFERRABLE INITIALLY IMMEDIATE
默认检查在每个语句后立即被执行。但在需要的时候,可以随时将约束检查延后。
在这种情况下该选项非常有用:多数时候需要在每个语句后立即检查约束,但偶尔有一批工作需要将约束检查延后。
NOT DEFERRABLE
永远无法将约束检查延后至事务提交时
presC# int unique
references movieExec(cert#)
deferrable initially deferred
set constraint myConstraint deferred
set constraint myConstraint immediate
SQL的create table语句可声明两种约束:1.在单一属性上的约束2.在整个元组上的约束
非空值约束
presC# int references movieExec(cert#) not null
这时候置空值原则就不能用了
基于属性的check约束
若数据库的修改没有改变与约束相关的属性,则不进行基于属性的check约束检查
presC# int references movieExec(cert#) check(presC#>=100000)
gender char(1) check(gender in('F','M'))
用check约束来模拟引用完整性约束是不行的
presC# int check (presC# in (select cert# from movieExec))
注意presC#不能被赋空值,这点和外键约束有点不一样
若改变movieExec关系,该变化对check不可见,违反check约束也会被执行
基于元组的check约束
check (gender='F' or name not like 'Ms.%')
类似与基于属性的check约束,基于元组的check约束对于其它关系不可见(若条件在子查询中提及其它关系,那个关系的改变会使得R中某些元组为假,check无法阻止这种改变)
若基于元组的检查没有子查询,那这类约束总可以保持
基于元组的约束比基于属性的更频繁的被检查,只要该元组的任何一个属性被改变,而不是仅当约束中被提及属性改变
给约束命名
name char(30) constraint nameIsKey primary key
修改约束
1.通过set constraint修改约束是否延期检查
set constraint myConstraint deferred
set constraint myConstraint immediate
2.通过alter table
alter table movieStar drop constraint nameIsKey
已删除的约束,就不可以再引用它的名字了
alter table movieStar add constraint nameIsKey
primary key(name)
加的是基于元组的约束
SQL中主动元素的最强有力的形式与特定的元组或元组的分量并不相关
这些元素被称为触发器和断言,它们是数据库模式的一部分,等同于表
DBMS必须推断数据库的任何更新是否影响断言的真假
创建断言
create assertion 断言名 check (条件)
当断言建立时,断言的条件必须是真,且永远保持是真
create assertion richPres check
(not exists
(select studio.name
from studio,movieExec
where presC#=cert# and netWorth<10000000
)
)
删除断言
drop assertion 断言名
check约束发生在对关系插入元组或属性修改时,并且若有子查询的话就不能确保成立(检查的是一条元组)
断言发生在对任何提及的关系做改变时,必须以某种方式聚集条件的结果(检查的是整个关系)