数据库中的参照完整性(ForeignKey)
之前在项⽬中遇到了这样⼀个问题,我举得简单的例⼦来说明,
⽐如我们有两个表,⼀个表(department)存放的是部门的信息,例如部门id,部门名称等;另⼀个表是员⼯表(staff),员⼯表⾥⾯肯定要存放每个员⼯所在的部门。那问题来了,如果我们这个时候删除了部门表中的某条记录,在staff表中会发⽣什么?
为了解答上⾯的问题,让我们先来回顾⼀下什么是参照完整性。
foreign key references用法我们常常希望保证在⼀个关系中给定属性集上的取值也在另⼀个关系的特定属性集的取值中出现。这种情况称为参照完整性(referential integrity)
正如我们可以⽤外码在SQL中的create table语句⼀部分的foreign key⼦句来声名。
例如staff表中的我们可以⽤ foreign key(dep_name) references department 来表明在每个员⼯组中指定的部门名称dep_name必须在department关系中存在。
更⼀般地,令关系r1和r2的属性集分别为R1和R2,主码分别为K1和K2。如果要求对r2中任意元祖t2,均存在r1中元祖t1使得t1.K1 = t2.α,我们称R2的⼦集α为参照关系r1中K1的外码(foreign key)
当我们违反了参照完整性约束时,通常的处理是拒绝执⾏导致完整性破坏的操作(即进⾏更新操作的事务被回滚)。但是,在foreign key⼦句中可以指明:如果被参照关系上的删除或更新动作违反了约束,那么系统必须采取⼀些步骤通过修改参照关系中的元祖来恢复完整性约束,⽽不是拒绝这样的操作。
来看下⾯的例⼦:
这是我们的department关系
create table department
( dept_name varchar(20),
building varchar(15),
primary key(department)
)
下⾯⼀般情况下我们的staff关系
<pre name="code" class="sql">create table staff
( ID varchar(15),
name varchar(20), not null
dept_name varchar(20),
primary key (ID),
foreign key(dept_name) reference department
)
下⾯是特定更新动作的staff关系
create table staff
( ID varchar(15),
name varchar(20), not null
dept_name varchar(20),
primary key (ID),
foreign key(dept_name) reference department
on delete cascade
on update cascade
)
由于有了外码声名相关联的on delete cascade⼦句,如果删除department中的元祖导致了此参照完整性约束被违反,则删除并不被系统拒绝,⽽是对staff关系作联机删除,即删除参照了被删除系的元祖。类似的,on update cascade会在更新时同步进⾏参照关系中元祖的更新。SQL还允许foreign key⼦句指明除了cascade以外的其他动作,如果约束被违反,可将参考与置为null(⽤set null代替 cascade),或者置为默认值(set default)。
但是,⼀般来说,我们习惯的⽤法是,不允许删除。如果实在要删除,可以在被参照关系中加⼀个字段,来表明当前的记录被删除了,这样也⽅便⽇后查询等相关操作。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论