1. 程式人生 > 資料庫 >mysql外來鍵基本功能與用法詳解

mysql外來鍵基本功能與用法詳解

本文例項講述了mysql外來鍵基本功能與用法。分享給大家供大家參考,具體如下:

本文內容:

  • 什麼是外來鍵
  • 外來鍵的增加
  • 外來鍵的修改和刪除
  • 外來鍵的約束模式

首發日期:2018-04-12


什麼是外來鍵:

  • 外來鍵就是表中存在一個欄位指向另外一個表的主鍵,那麼這個欄位就可以稱為外來鍵。
  • 一張表可以有多個外來鍵。
  • 外來鍵用於約束表與表之間的關係,可以說外來鍵是表之間的對映關係,這個關係可以幫助我們處理表之間關係的緊密性和存在性(比如學生表的cid班級號與班級表的id建立關聯,cid應該不能為不存在的,如果不增加外來鍵cid,沒有建立上關係,我們就不知道班級號不存在。)。
  • 或者說,外來鍵是告訴資料庫系統,我們所認為的關係,單純的資料,系統是不知道實際意義的,外來鍵就是告訴系統應該如何處理他們的關係。
  • 所以,外來鍵的核心是約束。

外來鍵的增加:

  • 建立外來鍵的前提是該欄位首先是一個索引,如果不是的話,建立外來鍵是會建立成一個普通索引【所以可以不在意】。
  • 建立外來鍵的另外一個前提是“指向表”已經建立,對於一個不存在的表,將無法使用外來鍵對應上。
  • 增加的方式:
    • 1.在建立表的時候定義,在所有欄位定義結束後使用foreign key(外來鍵欄位) references 指向表(主鍵)來 定義,比如image
    • 2.也可以修改欄位來增加: alter table 表名 add [constraint 外來鍵名字] foreign key(外來鍵欄位) references 父表(主鍵欄位);
      • constraint 外來鍵名字:可以幫助定義外來鍵的名字,但不建議使用,因為要求外來鍵名都唯一,而使用系統自定義的絕對不會重複,
create table student(
id int primary key auto_increment,name varchar(15) not null,gender varchar(10) not null,cid int,foreign key(cid) references class(id)
);
create table class(
id int primary key auto_increment,cname varchar(15)
);

補充:

  • 在Mysql中,如果儲存引擎不是innodb,那麼無法使外來鍵的約束作用生效,即使是能成功增加外來鍵。
  • 外來鍵名不能重複,所以不建議使用constraint 外來鍵名字

外來鍵的修改與刪除:

  • 修改:不能修改外來鍵資訊,如外來鍵指向之類的,只能先刪除再新增。
  • 刪除語法:alter table 表名 drop foreign key 外來鍵名;
    • 這裡的外來鍵名不是外來鍵欄位,而是外來鍵名。如果沒有使用constraint來定義,可以通過show create來查看錶建立語句中系統定義的外來鍵名。
    • image

補充:

  • 刪除外來鍵時,如果使用desc會看到表結構還有MUL,那是一個索引。因為建立外來鍵時,欄位會被建立成一個索引。如果不想保留,可以使用drop index 欄位名 on 表名.

外來鍵的約束模式:

  • 外來鍵是用來約束表之間的關係的。
  • (約定建立外來鍵的表稱為子表,指向的表稱為父表)
    • 針對子表:可以約束子表的插入和修改【這種約束是父表對子表的約束】
      • 涉及到外來鍵的插入和修改時,如果外來鍵欄位找不到對應的匹配那麼會插入\修改失敗(像插入選課記錄不可能插入一門課程表中沒有的課程)。
      • 比如:image
    • 針對父表:可以約束父表的刪除和更新,通常有可以以下幾種約束模式。【這種約束是子表對父表的約束】
      • 模式:
        • strict嚴格模式:涉及到外來鍵的刪除和更新時,如果對應記錄的主鍵資料已經被子表使用時,那麼無法刪除(像已經有人入學了某個班級,學校不可能犯傻去把某個班級刪除,只能刪除那些沒人入學的班級。)
        • cascade級聯模式:涉及到外來鍵的刪除和更新時,如果欄位已經被子表使用,子表中的資料會對應更新(像某個班改了班號,那麼學生表中的班別都對應更改;如果某個班被刪除,就刪除對應班的所有學生)
        • set null置空模式:涉及到外來鍵的刪除和更新時,如果欄位已經被子表使用,那麼子表中的外來鍵資料會置空(像某個班被刪掉了,不應該刪掉所有學生,而是應該給他們先置空再重新分配班別)【子表允許置空的前提是該欄位允許為空】
      • 其實可以給不同操作指定不同模式
      • 綜上所述(根據我的那些舉例),實際上,合適的舉措是刪除時置空(即使某個班太垃圾了,想刪除某個班,但也不應該將所有學生退學,而是將它們分到別的班),修改時級聯(允許更改班號,而且更改會更新到學生中)
      • 不同操作設定不同模式的設定方法(在子表中操作):foreign key(外來鍵欄位) references 父表(主鍵) on 操作 模式
        foreign key(外來鍵欄位) references 父表 (主鍵) on delete set null on update cascade;
-- 實驗表結構
create table class(
id int primary key auto_increment,cname varchar(15)
);
create table student2(
id int primary key auto_increment,foreign key(cid) references class(id) on delete set null on update cascade
);
-- 實驗表資料:
insert into class(cname) values("python"),("linux"),("java"),("html5");

insert into student2(name,gender,cid) values("Alice","female",1);
insert into student2(name,cid) values("John",2);
insert into student2(name,cid) values("Jack",3);
insert into student2(name,cid) values("Amy",4);

select * from student2;
select * from class;
-- 嘗試更新級聯
update class set id = 6 where cname="python";
select * from student2; -- 結果原來的python的cid=6
-- 嘗試刪除置空
delete from class where cname="java";
select * from student2; -- 結果原來的java的cid=null

補充:

  • 需要設定好約束模式,不要在多個子表中使用不同的約束模式,不然會衝突。

更多關於MySQL相關內容感興趣的讀者可檢視本站專題:《MySQL查詢技巧大全》、《MySQL常用函式大彙總》、《MySQL日誌操作技巧大全》、《MySQL事務操作技巧彙總》、《MySQL儲存過程技巧大全》及《MySQL資料庫鎖相關技巧彙總》

希望本文所述對大家MySQL資料庫計有所幫助。