外鍵約束


概念

  • 一張表的一個字段受限於另外一張表的一個字段對應的值。這里涉及到兩張表:被引用的表叫主表(父表),另外一張叫從表(子表)。
  • 它們的關系:主從表關系(父子表關系)
  • 子表:定義了外鍵的表

 外鍵的取值要么取父表中字段對應的值,要么取NULL值

 嚴重受限於父表

  • 父表:被引用的字段要具有唯一性(絕大多數都是用的父表的主鍵)

理論上是可以一張表里的一個字段引用另一個字段,但一般都是用兩張表

外鍵的實現

  • 建立表:

先建立父表,后建立子表(因為子表要用到父表)

除非先不考慮外鍵(建完表后再加),表多的時候可以不考慮建表順序。弊端:對數據要求很嚴格,一個垃圾數據都不能放

父表:

create table parent(
  id number primary key,
  name varchar2(30),

);

  

子表:

create table child(
  id number primary key,
  name varchar2(30),
  fid number constraint child_fid_fk references parent(id),
);

  • 插入數據:

一般先插入父表數據,再插入子表數據。除非把子表的外鍵值設置成NULL值,否則會出完整性錯誤

insert into child values(1, 'test1', 1);

 

要改為:先加入父表數據

insert into parent values(1, 'p1');
insert into parent values(2, 'p2');
insert into child values(1, 'test1', 1);

 

  • 刪除數據

子表中有關聯的數據,需要先刪子表,后刪父表。

select * from parent;

這里刪除父表的id為2的是沒關系的,只要沒有子表和它關聯就行

有關聯的必須先刪子表的數據,再刪父表的數據

   

delete from parent where id=1;

 

  • 刪除表

先刪子表,后刪父表

除非使用casecade  constraints  解除關聯

drop table parent;

 

先刪父表會出錯:

有一個被foreign  keys關聯的unique/primary  key的字段在表中

 

使用casecade  constraints解除關聯就可以刪掉父表

drop table parent cascade constranints;

外鍵的表級約束實現

父表:

create table parent(
  id number primary key,
  name varchar2(30),
);

 

子表:

create table child(
  id number primary key,
  name varchar2(30),
  fid number,
  constraint child_fid_fk foreign key(fid) references parent(id),
);

 

先建立表,后加外鍵

  • 子表s_emp :

里面有外鍵dept_id

  • 父表s_dept

查看腳本summit2_drop.sql發現:1270行

ALTER  TABLE s_emp
ADD  CONSTRAINT s_emp_dept_id_fk
FOREIGN  KEY (dept_id)  REFERENCES  s_dept(id);

級聯刪除和級聯置空

  • 級聯刪除:

在外鍵的最后,加上on delete  cascade  就是級聯刪除

再刪除主表數據時和主表關聯的子表數據也會刪除

  • 級聯置空

在在外鍵的最后,加上on  delete  set null就是級聯置空

再刪除主表數據時,會把和主表關聯的外鍵設置成NULL

演示:先刪表,不管有沒有

  (1)建立一張父表部門表

  • id number  primart  key  
  • name varchar2(30)
create table mydept(
  id nimber constraint mydept_pk primary key,
  name varchar2(30),
);

 

(2)建立一張子表  員工表

  • id number  primart  key  
  • name varchar2(30)
  • dept_id number  外鍵(關聯到部門表)
  • salary varchar2(30)

    

create table mtemp(
    id number constraint myepm_id_pk primary key,
  name varchar2(30),
  salary number,
  dept_id number constraint myemp_depy_id_fk reference mydept(id) on delete cascade,
);

  

desc mtemp;

 

(3)分別向兩張表中放入數據

部門表:

insert into mydept values(1, 'test1');
insert into mydept values(2,'test2');

 

select * from mydept;

 

員工表:

insert into mtemp values(1, 'empa', 5000,1);
insert into mtemp values(2, 'empb', 4500,1);
insert into mtemp values(3, 'empc', 5500,1);
insert into mtemp values(4, 'empd', 5800,2);
insert into mtemp values(5, 'empe', 5100,2);

 

select * from mtemp;

              提交數據:commit;

 

 (4)因為有on  delete cascade,所以刪除父表中的id為1的部分是可以的,並不會因為有關聯而刪不掉。

delete from mydept where id=1;

 

select * from mydept;

 

select * from mtemp;

 

(5)如果換為on  delete set  null,所以刪除父表中的id為1的部分是可以的,而子表的關聯的相應部分置為空  

delete from mydept where id=1;

  

select * from mydept;

 

select * from mtemp;

注意:如果是windows寫在.sql腳本里,則所有以上的代碼包括commit都寫入,再在cmd切到存放腳本的磁盤(如D)。

ftp傳到服務器上(192.168.0.26)

  • 這里清屏用!cls
  • put  要傳送的文件名把文件傳送到服務器
  • @要執行的文件名執行文件
  • 在SQL>@/user/openlab/要執行的腳本文件

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM