1. 程式人生 > >MySql多對多關係中外來鍵的應用

MySql多對多關係中外來鍵的應用

業務需求:使用者表r_user儲存使用者名稱等資訊。現需要給每個使用者設定工作基地,一個使用者可以有多個工作基地,多個使用者也可以有一個工作基地,即多對多關係。(外來鍵,若有兩個表A,B,C是A的主鍵,而B中也有C欄位,則C就是表B的外來鍵,外來鍵約束主要用來維護兩個表之間資料的一致性)

設計方案:

方案一:建立一張使用者基地表,與r_user與使用者基地表,保持一對多的關係,如圖所示,r_user的主鍵id做為r_user_base的外來鍵user_id。通過r_user中的id,在r_user_base表中load該使用者的所有工作基地。

方案二:建立一張個基地表base_info儲存目前存在的所有基地,再建一張user_base關係表。如圖所示,關係表user_base有兩個外來鍵user_id與base_id 

方案一的特點是,只需要鍵一張表就可以完成業務需求。缺點是不夠模組化,如果在其它地方還要用到基地資訊,則還要再建基地表

 

方案二的特點是,用一張關係表連線兩張資訊表。便於資訊表的維護與重複利用。

 

基於業務需求與以後擴充套件及重用性考慮,採用方案二實現需求。

 

在MySQL 3.23.44版本後,InnoDB引擎型別的表支援了外來鍵約束。

外來鍵的使用條件:

1.兩個表必須是InnoDB表,MyISAM表暫時不支援外來鍵(據說以後的版本有可能支援,但至少目前不支援);

2.外來鍵列必須建立了索引,MySQL 4.1.2以後的版本在建立外來鍵時會自動建立索引,但如果在較早的版本則需要顯示建立; 

3.外來鍵關係的兩個表的列必須是資料型別相似,也就是可以相互轉換型別的列,比如int和tinyint可以,而int和char則不可以;

 

外來鍵的定義語法:

[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)

    REFERENCES tbl_name (index_col_name, ...)

[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]

[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]

 cascade方式 

   在父表上update/delete記錄時,同步update/delete掉子表的匹配記錄 
   On delete cascade從mysql3.23.50開始可用; on update cascade從mysql4.0.8開始可用 。

 set null方式 

   在父表上update/delete記錄時,將子表上匹配記錄的列設為null 

   要注意子表的外來鍵列不能為not null 

   On delete set null從mysql3.23.50開始可用; on update set null從mysql4.0.8開始可用 
No action方式 

 如果子表中有匹配的記錄,則不允許對父表對應候選鍵進行update/delete操作 
   這個是ANSI SQL-92標準,從mysql4.0.8開始支援 
Restrict方式 

  同no action, 都是立即檢查外來鍵約束 

建立人員資訊表:

複製程式碼

1 CREATE TABLE `r_user` (
2   `id` bigint(20) NOT NULL AUTO_INCREMENT,
3   `NAME` varchar(20) DEFAULT NULL,
4   `PASSWORD` varchar(50) DEFAULT NULL,
5   `STAFF_NUM` varchar(20) DEFAULT NULL,
6    `USER_NAME` varchar(20) DEFAULT NULL,
7   PRIMARY KEY (`id`),
8   ) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8 

複製程式碼

建立基地資訊表

複製程式碼

1 CREATE TABLE `branch_info` (
2   `ID` bigint(20) NOT NULL AUTO_INCREMENT,
3    `BRANCH_CODE` varchar(255) DEFAULT NULL,
4   `BRANCH_DESC` varchar(255) DEFAULT NULL,
5   PRIMARY KEY (`ID`)
6 ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 

複製程式碼

關係表:

複製程式碼

1 CREATE TABLE `user_work_base` (
2   `id` bigint(20) NOT NULL AUTO_INCREMENT,
3   `version` int(11) NOT NULL,
4   `user_id` bigint(20) NOT NULL ,
5   `base_id` bigint(20) NOT NULL ,
6   PRIMARY KEY (`id`),
7   CONSTRAINT `user_work_base_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `r_user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
8   CONSTRAINT `user_work_base_ibfk_2` FOREIGN KEY (`base_id`) REFERENCES `branch_info` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
9 ) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8

複製程式碼

 

刪除人員r_user表中人員A,關係表user_base自動刪除A的關係資料。

 

如果外來鍵使用Restrict方式,只刪除A,則報錯。

Cannot delete or update a parent row: a foreign key constraint fails (`maircrew`,`user_work_base`, CONSTRAINT `FK41EB46D32AA89EA0` 

FOREIGN KEY (`user_id`) REFERENCES `r_user` (`id`))