数据库中的参照完整性(Foreign Key)

之前在项目中遇到了这样一个问题,我举得简单的例子来说明,

比如我们有两个表,一个表(department)存放的是部门的信息,例如部门id,部门名称等;另一个表是员工表(staff),员工表里面肯定要存放每个员工所在的部门。那问题来了,如果我们这个时候删除了部门表中的某条记录,在staff表中会发生什么?

为了解答上面的问题,让我们先来回顾一下什么是参照完整性

我们常常希望保证在一个关系中给定属性集上的取值也在另一个关系的特定属性集的取值中出现。这种情况称为参照完整性(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)。

但是,一般来说,我们习惯的用法是,不允许删除。如果实在要删除,可以在被参照关系中加一个字段,来表明当前的记录被删除了,这样也方便日后查询等相关操作。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 09:07:17

数据库中的参照完整性(Foreign Key)的相关文章

非关系型数据库中的「关系」实现

Knowledge Dependence:阅读文本前,你需要了解基本的关系型数据库与非关系型(NoSQL)数据库的概念和区别,以及 MongoDB(Mongoose)的简单实践. ? 这两三年来,伴随着大数据(Big Data)的空前火热,无论是在工程界还是科研界,非关系型数据库(NoSQL)都已经成为了一个热门话题. 相比于传统的关系型数据库,非关系型数据库天生从理念上就给数据存储提供了一种新的思路.而在实际应用中,它往往更轻巧灵活.扩展性高,并且更能胜任高性能.大数据量的场景. 值得一提的是

数据库中的索引、键和约束

一.索引 1.什么是索引? 索引是对数据库表中一列或多列的值进行排序的一种结构. 在关系型数据库中,索引是一种与表有关的数据库结构,是事实存在的.它可以使对于表的select等等操作更加快速,相当于一本书的目录. 对于一张表,如果我们想要找到某一列符合特定值的记录,第一种方法是全表搜索,匹配,然后把所有符合的记录列出,但是这样做会消耗大量数据库系统时间,并造成大量磁盘I/O操作:第二种就是在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索引中的ROWID(相当于页码)快速找到

ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails

MySQL在删除一张表时出现 可能是MySQL在InnoDB中设置了foreign key关联,造成无法更新或删除数据.可以通过设置FOREIGN_KEY_CHECKS变量来避免这种情况. SET FOREIGN_KEY_CHECKS = 0; 然后就可以删除表了. 删除完成后设置 SET FOREIGN_KEY_CHECKS = 1; drop table slow_log cascade; ERROR 1580 (HY000) at line 1: You cannot 'DROP' a l

MYSQL: Cannot delete or update a parent row: a foreign key constraint fails

这可能是MySQL在InnoDB中设置了foreign key关联,造成无法更新或删除数据.可以通过设置FOREIGN_KEY_CHECKS变量来避免这种情况. SET FOREIGN_KEY_CHECKS = 0; 删除完成后设置 SET FOREIGN_KEY_CHECKS = 1; 其他: 关闭唯一性校验 set unique_checks=0; set unique_checks=1;

MySQL:ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails

MySQL在删除一张表时出现 ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails 可能是MySQL在InnoDB中设置了foreign key关联,造成无法更新或删除数据.可以通过设置FOREIGN_KEY_CHECKS变量来避免这种情况. SET FOREIGN_KEY_CHECKS = 0; 然后就可以删除表了. 删除完成后设置 SET FOREIGN_KEY_CHE

mysql ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constrain fails

ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constrain fails. 可能是MySQL在InnoDB中设置了foreign key关联,造成无法更新或删除数据.可以通过设置FOREIGN_KEY_CHECKS变量来避免这种情况. 1.set foreign_key_checks=0; 2.删除要删除的表; 3.set foreign_key_checks=1; 原文地址:https://w

在数据库的设计中,外键(Foreign key)约束是否真的有必要呢?(一)

已经过去一段时间了.在数据库是否设置外键约束的问题,我和同事发生的争执.我是坚持使用外键约束,他们反对使用外键约束.于是,便有了这篇文章. 这篇文章主要是参考了StackOverFlow网站上的一个话题Are foreign keys really necessary in a databasedesign?(http://stackoverflow.com/questions/18717/are-foreign-keys-really-necessary-in-a-database-desig

数据库中的參照完整性(Foreign Key)

之前在项目中遇到了这样一个问题,我举得简单的样例来说明. 比方我们有两个表,一个表(department)存放的是部门的信息,比如部门id,部门名称等:还有一个表是员工表(staff),员工表里面肯定要存放每一个员工所在的部门. 那问题来了,假设我们这个时候删除了部门表中的某条记录,在staff表中会发生什么? 为了解答上面的问题,让我们先来回想一下什么是參照完整性. 我们经常希望保证在一个关系中给定属性集上的取值也在还有一个关系的特定属性集的取值中出现.这样的情况称为參照完整性(referen

MySql中的FOREIGN KEY

在mysql数据库编程中经常会出现几个表中存在某些相关属性,通常情况下我们可以通过使用外键约束来解决这个问题.但在删除表和修改表的结构时会出现一些小问题. 在删除表的时候Cannot delete or update a parent row: a foreign key constraint fails (...) 这是因为外键约束导致不能对表直接的进行相关操作. 取消外键约束  SET FOREIGN_KEY_CHECKS=0; 设置外键约束 SET FOREIGN_KEY_CKECKS=1