外键约束

外键约束

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

例如:一个人有多本书,如果要设计表,则现在需要设计两张数据表。

--删除数据表
DROP TABLE member PURGE;
DROP TABLE book PURGE;
--清空回收站
PURGE RECYCLEBIN;
--创建数据表
CREATE TABLE member(
	mid  NUMBER,
	name VARCHAR2(20)   NOT NULL,
	CONSTRAINT pk_mid PRIMARY KEY(mid)
);
CREATE TABLE book(
	bid  NUMBER,
	title VARCHAR2(20)   NOT NULL,
	mid  NUMBER
);
--测试数据
insert into member(mid,name)values (1,'韩信');
INSERT INTO member(mid,name)values (2,'李白'); 
INSERT INTO book(bid,title,mid) values (1,'java',1),
INSERT INTO book(bid,title,mid) values (2,'c',1),
INSERT INTO book(bid,title,mid) values (3,'c++',2),
INSERT INTO book(bid,title,mid) values (4,'python',2),
--提交事务
COMMIT;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BvEkMcIj-1580916075548)(C:\Users\016322605\Desktop\csdn\Oracle\捕获239.PNG)]

如果此时增加如下信息

insert into book(bid,title,mid) values (5,'c#',20);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cpfAUs19-1580916075551)(C:\Users\016322605\Desktop\csdn\Oracle\捕获240.PNG)]

此时插入成功,但是member表中并没有编号为20的成员信息,因为此时没有设置约束,所以即使现在父表(member)中不存在对应的编号,但是子表依然可以使用,这就是一个错误。

实际上,book表中的mid列的内容的取值应该是由member表中的mid列所决定,所以利用外键约束解决。在设置外键约束的时候必须要设置指定的外键列(book.mid列)需要与那张表的那个列有关。

范例:设置外键

--删除数据表
DROP TABLE member PURGE;
DROP TABLE book PURGE;
--清空回收站
PURGE RECYCLEBIN;
--创建数据表
CREATE TABLE member(
	mid  NUMBER,
	name VARCHAR2(20)   NOT NULL,
	CONSTRAINT pk_mid PRIMARY KEY(mid)
);
CREATE TABLE book(
	bid  NUMBER,
	title VARCHAR2(20)   NOT NULL,
	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 (1,'java',1);
INSERT INTO book(bid,title,mid) values (2,'c',1);
INSERT INTO book(bid,title,mid) values (3,'c++',2);
INSERT INTO book(bid,title,mid) values (4,'python',2);
--提交事务
COMMIT;

范例:增加正确数据

insert into book (bid,title,mid) values (5,'oracle',2);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VgVVbmFv-1580916075552)(C:\Users\016322605\Desktop\csdn\Oracle\捕获241.PNG)]

范例:增加错误数据

insert into book (bid,title,mid) values (6,'c#',20);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oZgn3veO-1580916075553)(C:\Users\016322605\Desktop\csdn\Oracle\捕获242.PNG)]

外键约束就相当于子表中的某一个字段的内容有父表来决定其数据的具体使用范围。

对外键而言最麻烦的是它存在许多限制。

  • 限制一:在删除父表之前需要先删除掉它所对应的全部字表后才可以删除

    范例:member是父表,book是子表,如果book没有删除,则member无法删除

    drop table member;
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T5y3Zvjt-1580916075554)(C:\Users\016322605\Desktop\csdn\Oracle\捕获243.PNG)]

范例:删除member表

drop table book;
drop table member;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n6Sv6fZ4-1580916075555)(C:\Users\016322605\Desktop\csdn\Oracle\捕获244.PNG)]

但是,有些时候会出现一些不合理的设计,将A表作为B表的父表,B表同时设置为A表的父表,于是无法删除。在Oracle里面专门提供了强制删除父表的操作,删除之后不关心子表。

范例:强制删除父表

drop tablej member cascade constraint;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3aCDpzuk-1580916075556)(C:\Users\016322605\Desktop\csdn\Oracle\捕获246.PNG)]

此时强制删除member表,这个时候子表book不会被删除,但是在实际开发过程中,尽量还是按照先后顺序删除。

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

    范例:错误的设计

    --删除数据表
    DROP TABLE member PURGE;
    DROP TABLE book PURGE;
    --清空回收站
    PURGE RECYCLEBIN;
    --创建数据表
    CREATE TABLE member(
    	mid  NUMBER,
    	name VARCHAR2(20)   NOT NULL,
    );
    CREATE TABLE book(
    	bid  NUMBER,
    	title VARCHAR2(20)   NOT NULL,
    	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 (1,'java',1);
    INSERT INTO book(bid,title,mid) values (2,'c',1);
    INSERT INTO book(bid,title,mid) values (3,'c++',2);
    INSERT INTO book(bid,title,mid) values (4,'python',2);
    --提交事务
    COMMIT;
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ruMM7gLn-1580916075559)(C:\Users\016322605\Desktop\csdn\Oracle\捕获247.PNG)]

  • 限制三:如果主表中的某一行数据有对应的子表数据,那么必须先删除子表中的全部数据

    恢复正常数据

    --删除数据表
    DROP TABLE member PURGE;
    DROP TABLE book PURGE;
    --清空回收站
    PURGE RECYCLEBIN;
    --创建数据表
    CREATE TABLE member(
    	mid  NUMBER,
    	name VARCHAR2(20)   NOT NULL,
    	CONSTRAINT pk_mid PRIMARY KEY(mid)
    );
    CREATE TABLE book(
    	bid  NUMBER,
    	title VARCHAR2(20)   NOT NULL,
    	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 (1,'java',1);
    INSERT INTO book(bid,title,mid) values (2,'c',1);
    INSERT INTO book(bid,title,mid) values (3,'c++',2);
    INSERT INTO book(bid,title,mid) values (4,'python',2);
    --提交事务
    COMMIT;
    

    范例:删除父表中的数据

    DELETE FROM member WHERE mid=1;
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eYSNqbo7-1580916075562)(C:\Users\016322605\Desktop\csdn\Oracle\捕获248.PNG)]

    由于book表中有子记录,所以父表的记录就无法删除。

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

    级联的关系有两种:级联删除、级联更新。

    • 级联删除:级联删除指的是在父表数据已经被删除的情况下,自动删除其对应的子表数据,在使用外键的时候,使用ON DELETE CASCAD即可。

      范例:级联删除

      --删除数据表
      DROP TABLE book PURGE;
      DROP TABLE member PURGE;
      
      --清空回收站
      PURGE RECYCLEBIN;
      --创建数据表
      CREATE TABLE member(
      	mid  NUMBER,
      	name VARCHAR2(20)   NOT NULL,
      	CONSTRAINT pk_mid PRIMARY KEY(mid)
      );
      CREATE TABLE book(
      	bid  NUMBER,
      	title VARCHAR2(20)   NOT NULL,
      	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 (1,'java',1);
      INSERT INTO book(bid,title,mid) values (2,'c',1);
      INSERT INTO book(bid,title,mid) values (3,'c++',2);
      INSERT INTO book(bid,title,mid) values (4,'python',2);
      --提交事务
      COMMIT;
      

      范例:级联删除

      delete from member where mid=1;
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hVXRUu9u-1580916075562)(C:\Users\016322605\Desktop\csdn\Oracle\捕获249.PNG)]

      此时,当删除了父表数据之后,子表数据会同时删除掉。

    • 级联更新

      如果说现在删除父表数据的时候,那么对应的子表数据的外键列就设置为null。使用ON DELETE NULL设置

      范例:设置级联更新

      --删除数据表
      DROP TABLE book PURGE;
      DROP TABLE member PURGE;
      
      --清空回收站
      PURGE RECYCLEBIN;
      --创建数据表
      CREATE TABLE member(
      	mid  NUMBER,
      	name VARCHAR2(20)   NOT NULL,
      	CONSTRAINT pk_mid PRIMARY KEY(mid)
      );
      CREATE TABLE book(
      	bid  NUMBER,
      	title VARCHAR2(20)   NOT NULL,
      	mid  NUMBER,
      	CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE NULL
      );
      --测试数据
      insert into member(mid,name)values (1,'韩信');
      INSERT INTO member(mid,name)values (2,'李白'); 
      INSERT INTO book(bid,title,mid) values (1,'java',1);
      INSERT INTO book(bid,title,mid) values (2,'c',1);
      INSERT INTO book(bid,title,mid) values (3,'c++',2);
      INSERT INTO book(bid,title,mid) values (4,'python',2);
      --提交事务
      COMMIT;
      

      范例:级联更新删除

      DELETE FROM member where mid=1;
      

      在这里插入图片描述
      什么时候使用级联,视具体场景而定。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Oracle 中的外键约束用于维护表之间的引用完整性,它定义了一个表中的一列或多列与另一个表中的一列或多列之间的关系。这个关系可以是单向的,也可以是双向的。 在 Oracle 中,创建外键约束需要满足以下条件: 1. 外键列和所引用的主键列的数据类型必须相同。 2. 外键列和所引用的主键列的长度必须相同。 3. 外键列和所引用的主键列必须都已经定义为 NOT NULL。 4. 外键列必须是索引列。 创建外键约束的语法如下: ``` ALTER TABLE 表名称 ADD CONSTRAINT 约束名称 FOREIGN KEY (外键列名称) REFERENCES 主键表名称 (主键列名称); ``` 其中,表名称是指需要添加外键约束的表名,约束名称是自定义的外键约束名称,外键列名称是需要添加外键约束的列名,主键表名称是被引用的表名,主键列名称是被引用表的主键列名。 例如,创建一个名为 "orders" 的表,它有一个外键列 "customer_id",引用了 "customers" 表的 "id" 列: ``` ALTER TABLE orders ADD CONSTRAINT orders_fk1 FOREIGN KEY (customer_id) REFERENCES customers (id); ``` ### 回答2: Oracle 外键约束是一种用于确保数据完整性的约束。它通过在列级别上定义关联关系,限制了一个表中的外键与另一个表中的主键或唯一键之间的关联关系。 外键约束可以用来保证数据的一致性和完整性。当我们在一个表中创建外键约束时,它会将指定列与另一个表的主键或唯一键进行关联。这样,在插入、更新或删除数据时,系统会自动检查外键约束,确保数据操作不会破坏关联关系。 外键约束可以有以下几个特点: 1. 外键关系必须在参照表上存在主键或唯一键约束。 2. 外键列的数据类型必须与参照列的数据类型匹配。 3. 外键列的值必须是参照表的主键或唯一键列中存在的值。 4. 当参照表的主键或唯一键更新或删除时,涉及到外键的操作也会受到影响。 外键约束的作用有以下几点: 1. 数据完整性:外键约束可以保证在关联表之间维护数据的一致性,防止无效或不合法数据的插入或更新。 2. 级联操作:定义级联操作可以在参照表上进行更新或删除操作时同时更新或删除关联的外键表中的数据,避免了手动处理关联数据的复杂性。 3. 查询优化:外键约束可以帮助优化查询,提高数据检索性能。 4. 数据模型的清晰性:通过外键约束,可以更清晰地定义表之间的关联关系,方便他人理解数据模型。 总之,Oracle 外键约束是一种强制性的关联关系,可以保证数据的一致性和完整性,提高数据库查询性能,并且使数据模型更加清晰易懂。 ### 回答3: Oracle外键约束是一种用来保持数据完整性的约束。它定义了两个表之间的关系,并防止数据库中的无效数据。外键约束在两个表之间创建引用,一个表中的一个列是另一个表的主键或唯一键。 通过外键约束,我们可以确保在从表中的外键列只包含在主表中已经存在的值。当我们向从表中插入或更新数据时,如果外键约束被违反,Oracle将抛出一个错误,阻止操作继续进行。 外键约束可以执行以下操作: 1. 防止删除或更新主表中的行,如果在从表中的外键列中仍然存在引用。这可以防止出现孤儿记录。 2. 防止插入或更新从表中的行,如果在主表中没有对应的主键或唯一键值。这可以防止出现无效的引用。 通过使用外键约束,我们可以确保数据库中的数据完整性和一致性。它可以减少数据错误和无效引用的可能性,并确保数据库中的相关数据保持一致。 外键约束可以在创建表时定义,也可以在后期通过ALTER TABLE语句添加。我们可以选择指定外键约束的名称,以及在违反约束时的动作,如RESTRICT、CASCADE或SET NULL。 总而言之,Oracle外键约束可以确保在表之间保持有效关系,防止无效引用和孤儿记录,并维护数据库的数据完整性和一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值