数据库中的參照完整性(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-08-14 18:44:59

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

在数据库的设计中,外键(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

mysql8.0数据库执行语句报1215-Cannot add foreign key constraint

原创公众号:路人甲Java     一位工作十年的前阿里P7大佬. 一.这个问题始终没整明白根本原因,只是换了个库再次执行可以成功. 1.在虚拟机中安装好linux系统后,想着装个mysql服务器吧,安装好之后就可以使用navicat进行连接操作了[具体搭建步骤后续更新]. 2.建好了也可以连接成功并创建了数据库,其他几张关联表也都执行成功,唯独在执行创建employees表的时候,界面报1215-Cannot add foreign key constraint,如下图: 3.经查阅资料,我做

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

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

MySQL数据库之-foreign key 外键(一对多、多对多、一对一)、修改表、复制表

今日重点:外键 一对多 多对多      一对一 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 一.引言: 我们在同一数据库创建的表时候,很多时候会出现相同数据的冗余问题,也就是说几个id

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

数据库添加数据报错:Cannot add or update a child row: a foreign key constraint fails

在更新表数据时出现了以下报错信息:Cannot add or update a child row: a foreign key constraint fails (o2o.tb_shop, CONSTRAINT fk_shop_profile FOREIGN KEY (owner_id) REFERENCES tb_person_info (user_id)) 也就是说tb_shop表中的涉及到的外键是fk_shop_profile,表tb_shop中的列owner_id和表tb_person

如何批量删除Redis数据库中的Key

借助 Linux 的 xargs 指令来完成 1 redis-cli keys "*" | xargs redis-cli del 2 //如果redis-cli没有设置成系统变量,需要指定redis-cli的完整路径 1 //带密码 2 redis-cli -a password keys "*" | xargs redis-cli -a password del 1 //访问指定库时候,下面的命令指定数据序号为0,即默认数据库 2 redis-cli -n 0

mysql中的外键foreign key

一.如果一张表中有一个非主键的字段指向了别一张表中的主键,就将该字段叫做外键. 一张表中可以有多个外键. 外键的默认作用有两点: 1.对子表(外键所在的表)的作用:子表在进行写操作的时候,如果外键字段在父表中找不到对应的匹配,操作就会失败. 2.对父表的作用:对父表的主键字段进行删和改时,如果对应的主键在子表中被引用,操作就会失败. 外键的定制作用----三种约束模式: district:严格模式(默认), 父表不能删除或更新一个被子表引用的记录. cascade:级联模式, 父表操作后,子表关

批量删除redis数据库中的key

在redis数据库中,如果大量以某些字段开头或结尾的key,一般都会用到命令keys进行模糊匹配.但是当我们想删除批量指定的keys,却犯愁了,因为redis没有提供相关的命令.那我们怎么操作能实现预期的效果呢? (1) 删除单个key 127.0.0.1:6379> del key 如果知道有限多个key的名字,以下操作也可以实现批量操作 127.0.0.1:6379> del key1 key2 key3 .... 当key的数量达到一定数量时,这个方法明显时不现实的. 注意:redis命