何時適合使用外鍵,何時不適合使用外鍵,使用外鍵有什麼好處和壞處?程序員
外鍵的好處:可使得兩張表關聯,保證數據的一致性和實現一些級聯操做。可是外鍵是否採用看業務應用場景,以及開發成本的,大體列下何時適合,何時不適合使用:sql
1. 互聯網行業應用不推薦使用外鍵: 用戶量大,併發度高,爲此數據庫服務器很容易成爲性能瓶頸,尤爲受IO能力限制,且不能輕易地水平擴展;如果把數據一致性的控制放到事務中,也即讓應用服務器承擔此部分的壓力,而引用服務器通常都是能夠作到輕鬆地水平的伸縮;【不適合】
2.傳統行業【適合】
1>.軟件應用的人數有限,換句話說是可控的;
2>.數據庫服務器的數據量也通常不會超大,且活躍數據有限;
綜合上述2句話描述,也即數據庫服務器的性能不是問題,因此不用過多考慮性能的問題;另外,使用外鍵能夠下降開發成本,藉助數據庫產品自身的觸發器能夠實現表與關聯表之間的數據一致性和更新;最後一點,使用外鍵的方式,還能夠作到開發人員和數據庫設計人員的分工,能夠爲程序員承擔更多的工做量;數據庫
爲什麼說外鍵有性能問題:
1.數據庫須要維護外鍵的內部管理;
2.外鍵等於把數據的一致性事務實現,所有交給數據庫服務器完成;
3.有了外鍵,當作一些涉及外鍵字段的增,刪,更新操做以後,須要觸發相關操做去檢查,而不得不消耗資源;
4.外鍵還會由於須要請求對其餘表內部加鎖而容易出現死鎖狀況;安全
2、使用方法服務器
一、建立外鍵的語法:併發
外鍵的定義語法:數據庫設計
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)性能
REFERENCES tbl_name (index_col_name, ...)設計
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]rest
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
該語法能夠在 CREATE TABLE 和 ALTER TABLE 時使用,若是不指定CONSTRAINT symbol,MYSQL會自動生成一個名字。
ON DELETE、ON UPDATE表示事件觸發限制,可設參數:
① RESTRICT(限制外表中的外鍵改動,默認值)
② CASCADE(跟隨外鍵改動)
③ SET NULL(設空值)
④ SET DEFAULT(設默認值)
⑤ NO ACTION(無動做,默認的)
在父表上進行update/delete以更新或刪除在子表中有一條或多條對應匹配行的候選鍵時,父表的行爲取決於:在定義子表的外鍵時指定的on update/on delete子句。
關鍵字 |
含義 |
CASCADE |
刪除包含與已刪除鍵值有參照關係的全部記錄 |
SET NULL |
修改包含與已刪除鍵值有參照關係的全部記錄,使用NULL值替換(只能用於已標記爲NOT NULL的字段) |
RESTRICT |
拒絕刪除要求,直到使用刪除鍵值的輔助表被手工刪除,而且沒有參照時(這是默認設置,也是最安全的設置) |
NO ACTION |
啥也不作 |
示例:
CREATE TABLE `task_basic` ( `task_id` int(10) NOT NULL AUTO_INCREMENT, `task_name` varchar(128) NOT NULL DEFAULT '', `description` varchar(1024) NOT NULL DEFAULT '', `last_modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`task_id`) ) ENGINE=InnoDB CHARSET=utf8 CREATE TABLE `job` ( `job_id` int(10) NOT NULL AUTO_INCREMENT, `task_id` int(10) NOT NULL DEFAULT '0', `job_status` int(10) NOT NULL DEFAULT '0', `last_modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`job_id`), KEY `task_id` (`task_id`), CONSTRAINT `job_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `task_basic` (`task_id`) ) ENGINE=InnoDB CHARSET=utf8 insert task_basic (task_name) values ('aaa') ,('bbb') ,('ccc'), ('ddd'); insert job ('task_id') values (1),(4); insert job (task_id) values (1),(5); #失敗,由於所依賴表中沒有 task_id=5的外鍵 ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`job`, CONSTRAINT `job_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `task_basic` (`task_id`)) delete from task_basic where task_id = 1; #失敗,由於默認外鍵是 restrict模式 ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`job`, CONSTRAINT `job_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `task_basic` (`task_id`))
刪除外鍵
語法: ALTER TABLE table-name DROP FOREIGN KEY key-id;
例: ALTER TABLE `tb_active` DROP FOREIGN KEY `FK_ID`