外键约束

news2024/11/30 10:46:21

目录

外键约束

对数据表进行初期设计,暂时不使用外键

验证限制三

验证级联删除

设置级联更新


Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645

外键约束

外键约束主要是在父子表关系中体现的一种约束操作。

下面通过一个具体的操作来观察一下为什么会有外键约束的存在。

例如,现在希望描述一种概念,两个人有多本书,如果要设计表就需要设计两张数据表

对数据表进行初期设计,暂时不使用外键

-- 删除数据表
DROP TABLE member PURGE ;
DROP TABLE book PURGE ;
-- 创建数据表
CREATE TABLE member(
	mid    NUMBER 	,
	name    VARCHAR2(20) ,
	CONSTRAINT pk_mid PRIMARY KEY(mid) 
) ;
CREATE TABLE book(
	bid		NUMBER ,
	title		VARCHAR2(20) ,
	mid		NUMBER 
) ;

上面这段代码创建两个数据表,member 和 book 数据表,下面分别向这两张表增加一些数

INSERT INTO member(mid,name) VALUES (1,'张三') ;
INSERT INTO member(mid,name) VALUES (2,'李四') ;
INSERT INTO book(bid,title,mid) VALUES (10,'Java开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (11,'Oracle开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (12,'Android开发',2) ;
INSERT INTO book(bid,title,mid) VALUES (13,'Object-C开发',2) ;

但是此时,也有可能会增加如下信息


INSERT INTO book(bid,title,mid) VALUES (20,'精神病防治',9) ;

此时 member 表中并没有编号为 9 的成员信息

但是由于此时没有设置所谓的约束,所以即使现在父表(member)中不存在对应的编号,那么子表也可以使用,这就是一个错误

实际上也就发现了,book 表中的 mid 列的内容的取值应该由 member 表中的 mid 列所决定,所以现在就可以利用外键约束来解决此类问题

在设置外键约束的时候必须要设置指定的外键列(book.mid列)需要与哪张表的哪个列有关联

-- 删除数据表
DROP TABLE member PURGE ;
DROP TABLE book PURGE ;
-- 创建数据表
CREATE TABLE member(
	mid		NUMBER 	,
	name		VARCHAR2(20) ,
	CONSTRAINT pk_mid PRIMARY KEY(mid) 
) ;
CREATE TABLE book(
	bid		NUMBER ,
	title		VARCHAR2(20) ,
	mid		NUMBER  ,
	CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid)
) ;

上面的代码中,在 member 表中创建了一个主键字段 mid,在 book 表中 mid 字段创建了外键

这个外键和 member 数据表中字段 mid 建立关联,此时 book.mid 列的内容取值范围由 member.mid 列所决定。如果内容正确,则可以保存。

此时可以和前面所述一样,分别向两个表中插入数据

INSERT INTO member(mid,name) VALUES (1,'张三') ;
INSERT INTO member(mid,name) VALUES (2,'李四') ;
INSERT INTO book(bid,title,mid) VALUES (10,'Java开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (11,'Oracle开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (12,'Android开发',2) ;
INSERT INTO book(bid,title,mid) VALUES (13,'Object-C开发',2) ;

如果此时增加错误的数据,来看一下会出现什么情况。向数据表 book 中增加错误的数据,member.mid 没有为 9 的数据

INSERT INTO book(bid,title,mid) VALUES (20,'精神病防治',9) ;

那么此时会出现如下错误信息

ORA-02291: 违反完整约束条件 (SCOTT.FK_MID) - 未找到父项关键字

所谓的外键,就相当于子表中的某一个字段的内容由父表来决定其具体的数据范围。

对外键而言,比较麻烦的是它存在有许多限制。限制一:在删除父表时,需要先删除掉它所对应的全部子表。

member 是父表,book 是子表,如果说现在 book 表没有删除,那么 member 表就无法删除

drop table member;

使用上面代码会出现如下错误信息

ORA-02449: 表中的唯一 / 主键被外键引用

所以需要改变删除顺序

drop table member;
drop table member;

但是有些时候,一些数据库设计者,将 A 表作为 B 表的父表,B 表也同时设置为 A 表的父表,于是就都删不掉了。

为此,在 Oracle 里面专门提供了一个强制删除父表的操作,删除之后不关心子表

drop table member cascade constraint;

此时将强制删除 member 表,但子表不会被删除。但是从实际开发来说,尽量还是按照先后顺序删除。

限制二:如果要作为子表外键的父表列,那么这个列必须设置唯一约束或主键约束。

例如,上面的范例中 member 表中 mid 列被设置成主键约束。

限制三:如果现在主表中某一行数据有对应的子表数据,那么必须先删除子表中的全部数据之后才可以删除父表中的数据。

下面通过一个范例,来理解这个限制的真实意义

验证限制三

首先运行下面代码,建立数据表,并向数据表中插入数据

-- 删除数据表
DROP TABLE book PURGE ;
DROP TABLE member PURGE ;
-- 创建数据表
CREATE TABLE member(
	mid		NUMBER 	,
	name		VARCHAR2(20) ,
	CONSTRAINT pk_mid PRIMARY KEY(mid)
) ;
CREATE TABLE book(
	bid		NUMBER ,
	title		VARCHAR2(20) ,
	mid		NUMBER  ,
	CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid)
) ;
INSERT INTO member(mid,name) VALUES (1,'张三') ;
INSERT INTO member(mid,name) VALUES (2,'李四') ;
INSERT INTO book(bid,title,mid) VALUES (10,'Java开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (11,'Oracle开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (12,'Android开发',2) ;
INSERT INTO book(bid,title,mid) VALUES (13,'Object-C开发',2) ;

运行上面的代码后,可以观察到,member 和 book 数据表中都有 mid 为 1 的数据,即 member 和book 表中有对应的关联

运行下面的删除语句

DELETE FROM member WHERE mid=1 ;

这时会出现如下错误信息

ORA-02292: 违反完整约束条件 (SCOTT.FK_MID) - 已找到子记录

发生这种错误是由于 book 表中有子记录,所以父表的记录就无法删除了。

如果说现在不想受到子记录的困扰,那么就可以使用级联操作。

级联的关系有两种:级联删除、级联更新。级联删除:在父表数据已经被删除的情况下,自动删除其对应子表的数据。

在定义外键的时候使用 ON DELETE CASCADE 即可

验证级联删除

-- 删除数据表
DROP TABLE book PURGE ;
DROP TABLE member PURGE ;
-- 创建数据表
CREATE TABLE member(
	mid		NUMBER 	,
	name		VARCHAR2(20) ,
	CONSTRAINT pk_mid PRIMARY KEY(mid)
) ;
CREATE TABLE book(
	bid		NUMBER ,
	title		VARCHAR2(20) ,
	mid		NUMBER  ,
	CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE CASCADE
) ;

INSERT INTO member(mid,name) VALUES (1,'张三') ;
INSERT INTO member(mid,name) VALUES (2,'李四') ;
INSERT INTO book(bid,title,mid) VALUES (10,'Java开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (11,'Oracle开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (12,'Android开发',2) ;
INSERT INTO book(bid,title,mid) VALUES (13,'Object-C开发',2) ;

 在上面代码中,在 book 数据表中定义外键的时候,使用了“ON DELETE CASCADE”。运行下面的删除语句

DELETE FROM member WHERE mid=1 ;

我们可以看到,此时当删除了父表数据之后,子表数据会同时删除掉。

级联更新:如果删除父表数据的时候,不想子表含有关联数据的记录也同时被删除掉,但是这时外键字段的值没有对应的关联数据了,那么对应的子表数据的外键字段就可以设置为 null。这种结果可以使用 ON DELETE SET NULL 设置

设置级联更新

-- 删除数据表
DROP TABLE book PURGE ;
DROP TABLE member PURGE ;
-- 创建数据表
CREATE TABLE member(
	mid		NUMBER 	,
	name		VARCHAR2(20) ,
	CONSTRAINT pk_mid PRIMARY KEY(mid)
) ;
CREATE TABLE book(
	bid		NUMBER ,
	title		VARCHAR2(20) ,
	mid		NUMBER  ,
	CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE SET NULL
) ;

INSERT INTO member(mid,name) VALUES (1,'张三') ;
INSERT INTO member(mid,name) VALUES (2,'李四') ;
INSERT INTO book(bid,title,mid) VALUES (10,'Java开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (11,'Oracle开发',1) ;
INSERT INTO book(bid,title,mid) VALUES (12,'Android开发',2) ;
INSERT INTO book(bid,title,mid) VALUES (13,'Object-C开发',2) ;

 此时如果运行语句“DELETE FROM member WHERE mid=1”,那么 member 中所有符合条件“mid=1”的行都会被删除掉,

但是对应子表 book 中原先对应的 mid=1 都会更新为 null

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1529519.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【二叉树】算法例题

目录 九、二叉树 68. 二叉树的最大深度 ① 69. 相同的树 ① √ 70. 翻转二叉树 ① 71. 对称二叉树 ① 72. 从前序与中序遍历序列构造二叉树 ② 73. 从中序与后续遍历序列构造二叉树 ② 74. 填充每个节点的下一个右侧节点指针 II ② 75. 二叉树展开为链表 ② 76.…

鸿蒙实战开发:【FaultLoggerd组件】讲解

简介 Faultloggerd部件是OpenHarmony中C/C运行时崩溃临时日志的生成及管理模块。面向基于 Rust 开发的部件,Faultloggerd 提供了Rust Panic故障日志生成能力。系统开发者可以在预设的路径下找到故障日志,定位相关问题。 架构 Native InnerKits 接口 Si…

Marin说PCB之电源完整性之直流压降仿真CST--03

本期内容主要讲解的是关于在CST软件上电源直流压降仿真VRM的一些相关参数设置,小编我在之前文章中有说到过如何利用CST仿真电源信号的直流压降,不过有一些问题我这边再去补充一些。 首先就是VRM芯片的设置了,小编我还是按照之前那样设置&…

腾讯云k8s容器服务

1、新建一个集群 这个网址: 登录登录 - 腾讯云 2、选择第一个 3、名字随便起一个,然后基本默认就行 4、 组件配置直接跳过,信息确认,等待集群初始化,等10分钟左右(容器服务需要充点钱才行) 5…

学习vue3第八节(自定义指令 directive)

1、自定义指令的作用: 自定义指令是用来操作底层DOM的,尽管vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和拓展,不仅仅可用于定义任何DOM操作,并且是可以重复使用。 自定义…

杨氏矩阵的查找(复杂度<O(N))

题目: 解释:时间复杂度小于O(N)即不要一个一个的去遍历查找。 思路: 一个33的二维数组如图所示: 一:先找到一个最关键的数字,3(下标为0,2) 关键数的关键之处在于(处于…

过拟合欠拟合

问题:训练数据训练的很好啊,误差也不大,为什么在测试集上面有问题呢? 当算法在某个数据集当中出现这种情况,可能就出现了过拟合现象。 1、 什么是过拟合与欠拟合 欠拟合 过拟合 分析第一种情况:因为机器…

[Python人工智能] 四十三.命名实体识别 (4)利用bert4keras构建Bert+BiLSTM-CRF实体识别模型

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解如何实现中文命名实体识别研究,构建BiGRU-CRF模型实现。这篇文章将继续以中文语料为主,介绍融合Bert的实体识别研究,使用bert4keras和kears包来构建Bert+BiLSTM-CRF模型。然而,该代码最终结…

Linux用户、用户组

用户管理命令: 首先要先知道两个配置文件:/etc/group 用户组配置文件/etc/passwd 保存了所有用户的用于读取的必要信息**/etc/shadow **是 Linux 系统中用于存储用户密码信息的文件。这个文件也被称为“影子文件”,因为它包含了 /etc/passwd…

Unity发布webgl设置占满浏览器运行

Unity发布webgl设置占满浏览器运行 Unity发布webgl的时候index.html的模板文件 模板文件路径,根据自己的需求修改。 C:\Program Files\Unity\Hub\Editor\2021.1.18f1c1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\WebGLTemplates\Default再桌面新建一个t…

chatgpt大模型基础学习

chatgpt大模型基础学习 1. 吴恩达提示工程2. 大模型说的token是什么 1. 吴恩达提示工程 知乎 https://zhuanlan.zhihu.com/p/626290417?utm_id0 中文版 https://mp.weixin.qq.com/s?__bizMzkwMjQ5MzExMg&mid2247483714&idx1&sn5e905f5ec6196f6dc2187db2a8618f02&…

Jmeter接口测试,一篇足矣。

🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号:互联网杂货铺,回复1 ,免费获取软件测试全套资料,资料在手,涨薪更快 现在对测试人员的要求越来越高,不仅仅要做好…

使用强森算法求任意两点之间最短路径

对于强森算法的算法思想,如果给定的图中是没有负数的边,那么就可以使用迪杰斯特拉算法来进行遍历每个节点,找到它与其他节点的最短路径,而如果给定的图中是存在负数的边,但是不存在负数的环的时候,那么就可以使用算法对边长做一些修改并且可以准确的找到给定的两个节点之…

各种窗函数对脉压结果的影响

雷达导论专栏总目录链接: 雷达导论专栏总目录-CSDN博客 1. 各类窗函数 有几个窗函数的系数可配,配置如下: tukeywin(N,0.75)kaiser(N,2.5)gausswin(N,1.5)taylorwin(N,3,-24)2. 时域加窗 时域加窗时,直接加在匹配滤波函数上:Htw=exp(1j*pi*K*tp.^2).*win;。那么矩形窗就相…

手撕算法-最长公共子序列(二)

最长公共子序列(二) 分析:典型的动态规划,直接看代码了。 代码: import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** longest common sub…

【第十四章】改进神经网络学习方式-权重初始化

当我们创建神经网络时,我们必须为初始权重和偏置做出选择。到目前为止,我们一直根据我在第一章中简要讨论过的一种方法来选择它们。提醒一下,那种方法是使用独立的高斯随机变量来选择权重和偏置,使它们的均值为0,标准差…

从C++源代码到可执行文件?

从C源代码到可执行文件的转换是一个涉及多个步骤的过程,通常包括预处理、编译、汇编和链接四个主要阶段: 1.四个阶段 预处理 (Preprocessing) 预处理器(如cpp)首先读取原始的C源代码文件,并对其进行一系列文本替换操作…

【考研数学】武忠祥全年各阶段搭配用书汇总

如果选武忠祥,讲义方面选择基础篇和辅导讲义即可。分别在基础阶段和强化阶段使用。 此外复习全书不用买(无论是基础篇还是提高篇都不用)你以后可能会看到它的各种推广,不要轻信,有讲义的情况下全书很难利用得上。 武…

Positive Technologies 专家发现的漏洞已在 ABB 控制器中得到修复

🌟 我们的同事一如既往地表现出色:应用分析专家 Natalia Tlyapova 和 Denis Goryushev 因发现 Freelance AC 900F 和 AC 700F 控制器中的两个漏洞而受到 ABB 的表彰。 这些设备用于自动化大规模连续循环生产设施和构建企业配送控制系统。利用这些漏洞的…

一文彻底搞懂TCP三次握手和四次挥手,及常见的面试题带答案

TCP(传输控制协议)是一种可靠的、面向连接的协议。在TCP/IP协议栈中,它负责在两个网络应用程序之间建立可靠的会话连接。TCP通过“三次握手”建立连接,通过“四次挥手”断开连接。本文将详细介绍这两个过程,并给出一些…