Oracle中约束的创建与管理之外键约束

【外键约束】(FOREIGN KEY FK)
如果单纯的去解释外键并不好解释,下面通过一个数据表的操作来观察一下为什么需要外键。外键与其他的约束不同,它是作用于两张数据表上的约束。
·问题分析
    emp和dept表,这两个表的基本关系,每一个部门可以包含有多个雇员信息,属于一对多关系,dept应该是一个父表,而emp是一个子表,所以在emp子表里面设置有一个deptno的字段。
    模拟以上的功能实现一个人有多本书的操作。需要定义两张表。
DROP TABLE member PURGE;
DROP TABLE book PURGE;
CREATE TABLE member(
mid NUMBER,
name VARCHAR2(20)    NOT NULL,
CONSTRAINT pk_mid PRIMARY KEY(mid)
);
CREATE TABLE book(
bid NUMBER,
title VARCHAR2(20),
mid NUMBER,
CONSTRAINT pk_bid PRIMARY KEY(bid)
);
下面开始为表中增加数据。
·范例:增加有意义的数据
INSERT INTO member(mid,name) VALUES (10,'张三');
INSERT INTO member(mid,name) VALUES (20,'李四');
INSERT INTO member(mid,name) VALUES (30,'王五');
INSERT INTO book(bid,title,mid) VALUES (10001,'Java',10);
INSERT INTO book(bid,title,mid) VALUES (10002,'Jsp',10);
INSERT INTO book(bid,title,mid) VALUES (10003,'MVC',10);
INSERT INTO book(bid,title,mid) VALUES (20001,'Oracle',20);
INSERT INTO book(bid,title,mid) VALUES (20002,'DB2',20);
INSERT INTO book(bid,title,mid) VALUES (20003,' Mongo',20);
INSERT INTO book(bid,title,mid) VALUES (30001,'jQuery',30);
INSERT INTO book(bid,title,mid) VALUES (30002,'AngularJS',30);
    所有增加的图书信息中的人员编号在member表里面都存在。
·范例:增加错误信息
INSERT INTO book(bid,title,mid) VALUES (88888,'计算机',90);
    明明在member里面没有“mid = 90”的人员信息,但是在book表里面发现这样的信息却可以保存,也就发现以上代码的问题出现在:子表中的数据与父表中的数据不一致 (book子表中的mid的范围赢该由父表memeber中的mid来决定)。所谓的外键关联指的就是控制子表中某一个列的内容与父表中的数据范围相匹配,使用FOREIGN KEY来表示
·范例:增加外键
DROP TABLE member PURGE;
DROP TABLE book PURGE;
CREATE TABLE member(
mid NUMBER,
name VARCHAR2(20)    NOT NULL,
CONSTRAINT pk_mid PRIMARY KEY(mid)
);
CREATE TABLE book(
bid NUMBER,
title VARCHAR2(20),
mid NUMBER,
CONSTRAINT pk_bid PRIMARY KEY(bid),
CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid)
);
如果此时关联的数据正确,那么可以正常的保存,如果此时book表中要增加的数据关联有问题(父表不存在此内容),那么就会出现如下的错误提示:
·添加正确数据
INSERT INTO member(mid,name) VALUES (10,'张三');
INSERT INTO member(mid,name) VALUES (20,'李四');
INSERT INTO member(mid,name) VALUES (30,'王五');


INSERT INTO book(bid,title,mid) VALUES (10001,'Java',10);
INSERT INTO book(bid,title,mid) VALUES (10002,'Jsp',10);
INSERT INTO book(bid,title,mid) VALUES (10003,'MVC',10);
INSERT INTO book(bid,title,mid) VALUES (20001,'Oracle',20);
INSERT INTO book(bid,title,mid) VALUES (20002,'DB2',20);
INSERT INTO book(bid,title,mid) VALUES (20003,' Mongo',20);
INSERT INTO book(bid,title,mid) VALUES (30001,'jQuery',30);
INSERT INTO book(bid,title,mid) VALUES (30002,'AngularJS',30);
·添加错误数据
INSERT INTO book(bid,title,mid) VALUES (88888,'计算机',90);
报错:第 1 行出现错误:
ORA-02291: 违反完整约束条件 (SCOTT.FK_MID) - 未找到父项关键字
因为在member表的mid列上没有内容为90的数据,所以以上的错误数据信息无法保存。


虽然清楚了外键的作用,但是一旦使用到了外键那么就比较麻烦了,因为所有的约束外键是针对于两张数据表的约束,所以在表对象与表数据的操作上就会存在有限制
·限制一:如果表中存在有外键关系,在删除父表之前一定要先删除子表
    如果没有删除子表就删除父表,则报错:
第 1 行出现错误:
ORA-02449: 表中的唯一/主键被外键引用


DROP TABLE book PURGE;(子表)
DROP TABLE member PURGE;(父表)
    以上是一个正常逻辑,并且在编写代码的过程之中应该按照正常逻辑编写程序。现假设有两张表,A表和B表,A表有B表的外键,B表有A表的外键。这个就没法区分了,所以为了解决这种尴尬的问题,提供有一种强制删除。
·范例:强制删除
DROP TABLE member CASCADE CONSTRAINT;
此时,不再关注子表是否存在,父表直接强制删除,不到万不得已,不要使用此类操作。


·限制二 :父表中作为子表关联字段,必须设置为主键约束或者是唯一约束,否则不能作为外键
CREATE TABLE member(
mid NUMBER,
name VARCHAR2(20)    NOT NULL
);
CREATE TABLE book(
bid NUMBER,
title VARCHAR2(20),
mid NUMBER,
CONSTRAINT pk_bid PRIMARY KEY(bid),
CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid)
);


  报错:
第 6 行出现错误:
ORA-02270: 此列列表的唯一关键字或主键不匹配  
·限制三:默认情况下,如果父表记录中有对应的子表记录,那么父表记录无法被删除。
DELETE FROM member WHERE mid = 10;
报错:第 1 行出现错误:
ORA-02292: 违反完整约束条件 (SCOTT.FK_MID) - 已找到子记录
因为book表现在存在有member表对应记录的资子内容,如果要想删除则应该先删除子表数据后再删除父表数据。
正确删除:
DELETE FROM book WHERE mid = 10;
DELETE FROM member WHERE mid = 10;
    如果说member表与10张表都存在有外键关系。 这样先删除子表再删除父表的过程就不方便了,有些时候希望父表数据一删除,对应的子表数据也自动删除就可以了,这就需要配置数据的级联操作。
·数据的级联删除:ON DELETE CASCADE:
DROP TABLE book PURGE;
DROP TABLE member PURGE;
CREATE TABLE member(
mid NUMBER,
name VARCHAR2(20)    NOT NULL,
CONSTRAINT pk_mid PRIMARY KEY(mid)
);
CREATE TABLE book(
bid NUMBER,
title VARCHAR2(20),
mid NUMBER,
CONSTRAINT pk_bid PRIMARY KEY(bid),
CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE CASCADE

·级联更新:当父表数据被删除后,子表对应的内容设置为null,使用 ON DELETE SET NULL完成
ROP TABLE book PURGE;
DROP TABLE member PURGE;
CREATE TABLE member(
mid NUMBER,
name VARCHAR2(20)    NOT NULL,
CONSTRAINT pk_mid PRIMARY KEY(mid)
);
CREATE TABLE book(
bid NUMBER,
title VARCHAR2(20),
mid NUMBER,
CONSTRAINT pk_bid PRIMARY KEY(bid),
CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE SET NULL
);
是否选择数据的级联操作,或者是选择哪类级级联是根据开发要求决定的
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值