1.外键约束建立在从表上
主表被引用的列要求值要唯一即主从的联系必须为1:N或者1:1
多对多的模式最好采用中间表的形式,存储各个表的外键,参考下图
2.oracle级联操作on delete分为
2.1no action
- 父表子表对插入删除的影响
假设父表为school,子表为class/student
插入时,插入CHILD TABLE 才会触发Referential Integrity(完整性约束条件)
Eg.你无法将一个班级归到不存在的学校中
- 删除的影响
删除父表(或主表primary table)才会触发完整性约束条件,可以利用级联删除,实现删除父表相应记录同时删除子表(从表或slave table)相应记录。
Eg.学校中有班级就不能注销学校
- 更新的影响
利用触发器实现级联更新。
2.2cascade级联删除
主表被引用的列的数据删除了,级联删除子表相应的数据行
2.3set null
主表中被引用列的数据被删除时子表的外键被指为Null(这就要求外键可以为null)
3.级联更新
oracle本身没有级联更新但是可以借助触发器实现,同时利用延迟约束
3.1延迟约束
- 延迟约束,只在提交的时候进行约束检查
- 非延迟约束,在修改记录时(对应PL/SQL中的post change按钮 或者DML语句commit前的update)会立刻进行约束条件检查,如果违反越约束条件便不能修改。
通过延迟约束在主表上建立触发器,触发器更新子表的外键,来实现级联更新。
注意:当表的外键引用同一个表的主键时,触发器无法进行级联更新(笔者猜测变异表)?
3.2级联更新流程
主表建立触发器更新从表,从表建立外键使用deferrable关键字实现延迟约束。
4.实例
外键使用、级联更新、删除实例
----------------------------------------primary table------------------------------------------------
-- Create primary table
create table SCHOOLE
(
pid NUMBER not null,
pname VARCHAR2(30)
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
--create trigger for cascade update
CREATE OR REPLACE TRIGGER TRG_SCHOOL_UPDATE
AFTER UPDATE OF PID ON SCHOOLE
FOR EACH ROW
BEGIN
IF :old.pid<>:new.pid THEN
UPDATE student SET SCHOOLEID=:new.pid WHERE SCHOOLEID=:old.pid;
END IF;
END;
-- Create/Recreate primary, unique and foreign key constraints
alter table SCHOOLE
add constraint PK_SCHOOLE primary key (PID)
using index
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
---------------------------------------------------slave table cascade delete---------------------------------------------
-- Create table slave table
create table STUDENT
(
pid NUMBER not null,
pname VARCHAR2(15),
schooleid NUMBER
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
-- Create/Recreate primary, unique and foreign key constraints
alter table STUDENT
add constraint PK_STUDENT primary key (PID)
using index
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table STUDENT
add constraint FK_STUDENT_SCHOOLE foreign key (SCHOOLEID)--从表字段(外键)
references SCHOOLE (PID) on delete cascade;--级联删除
-------------------------------------------slave table cascade update-------------------------------------------------------
-- Create table
create table STUDENT
(
pid NUMBER not null,
pname VARCHAR2(15),
schooleid NUMBER
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
-- Create/Recreate primary, unique and foreign key constraints
alter table STUDENT
add constraint PK_STUDENT primary key (PID)
using index
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table STUDENT
add constraint FK_STUDENT_SCHOOLE foreign key (SCHOOLEID)
references SCHOOLE (PID) on delete cascade
deferrable;--延迟约束
参考文献
Oracle外键级联删除和级联更新
https://www.2cto.com/database/201507/417496.html
多对多关系中外键的应用
https://blog.csdn.net/qq_34146899/article/details/52558664