一密末、定義
- 外鍵約束(FOREIGN KEY Constraint) 赡若,用來維護(hù)從表(Child Table)和主表(Parent Table)之間的引用完整性.
- 外鍵約束是個有爭議性的約束,它一方面能夠維護(hù)數(shù)據(jù)庫的數(shù)據(jù)一致性蛾号,數(shù)據(jù)的完整性,防止錯誤的垃圾數(shù)據(jù)入庫摸屠;
- 另外一方面它會增加表插入景埃、更新等SQL性能的額外開銷媒至,不少系統(tǒng)里面通過業(yè)務(wù)邏輯控制來取消外鍵約束
二 顶别、語法格式
1、添加約束
- 行級添加
CREATE TABLE 表名 ( 列名 數(shù)據(jù)類型 REFERENCES 參照表(參照列名) [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}] [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}] ... ) --參照列名一般是主表的主鍵
- 表級添加
CREATE TABLE 表名 ( 列名 數(shù)據(jù)類型 , ... CONSTRAINT 約束名稱(FK_TABLE_NAME) FOREIGN KEY(約束列) REFERENCES 參照表(參照列名) [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}] [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}] ) -- 外鍵名一般命名為《FK_表名_參照列名》
- 創(chuàng)建表之后添加
ALTER TABLE 表名 ADD CONSTRAINT `約束名` FOREIGN KEY ('約束列') REFERENCES 參照表 ('列名') [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}] [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
2拒啰、刪除約束
- 語法格式
ALTER TABLE 表名 DROP FOREIGN KEY 外鍵名;
三驯绎、示例代碼
- 主表
-- 主表 CREATE TABLE TB_USER( UID INT(10) PRIMARY KEY AUTO_INCREMENT, USERNAME VARCHAR(64) );
- 行級添加
-- 子表 CREATE TABLE TB_ADDRESS( ADDRESS_ID int(10), USERNAME VARCHAR(64), UID int(10) REFERENCES TB_USER(UID) );
- 表級添加
-- 在子表上 CREATE TABLE TB_ADDRESS( ADDRESS_ID int(10), USERNAME VARCHAR(64), UID int(10) , CONSTRAINT FK_TBUSER_UID FOREIGN KEY(UID) REFERENCES TB_USER(UID) ON DELETE SET NULL );
- 創(chuàng)建表之后添加
-- 創(chuàng)建子表 CREATE TABLE TB_ADDRESS( ADDRESS_ID int(10), USERNAME VARCHAR(64), UID int(10) REFERENCES TB_USER(UID) , ); -- 主表子表創(chuàng)建完成之后單獨(dú)添加 ALTER TABLE TB_ADDRESS ADD CONSTRAINT `fk_user_uid` FOREIGN KEY (uid) REFERENCES t_user (uid) ON DELETE NO ACTION ON UPDATE NO ACTION;
- 刪除外鍵
ALTER TABLE TB_ADDRESS DROP FOREIGN KEY 'fk_user_uid';
四、ON DELETE 與ON UPDATE
1谋旦、說明
表示刪除或者更新主表的數(shù)據(jù)剩失、子表如何操作
2、可選值
- RESTRICT 與 No Action(sql標(biāo)準(zhǔn)):
RESTRICT(默認(rèn)值)册着,當(dāng)在父表(即外鍵的來源表)中刪除對應(yīng)記錄時(shí)拴孤,首先檢查該記錄是否有對應(yīng)外鍵,如果有則不允許刪除 - CASCADE:
當(dāng)在父表(即外鍵的來源表)中刪除對應(yīng)記錄時(shí)甲捏,首先檢查該記錄是否有對應(yīng)外鍵演熟,如果有則也刪除外鍵在子表(即包含外鍵的表)中的記錄 - SET NULL:
當(dāng)在父表(即外鍵的來源表)中刪除對應(yīng)記錄時(shí),首先檢查該記錄是否有對應(yīng)外鍵司顿,如果有則設(shè)置子表中該外鍵值為null(不過這就要求該外鍵允許取null) 芒粹,支持ON DELETE SET NULL和
ON UPDATE - SET DEFAULT:
InnoDB目前不支持。
五大溜、對DML與DDL的影響
1化漆、INSERT
只有操作是在子表或從表這一端時(shí)才會產(chǎn)生違反引用完整性約束的問題,父表則不受影響钦奋。
2座云、DELETE
只有操作是在父表或主表這一端時(shí)才會產(chǎn)生違反引用完整性約束的問題,子表則會根據(jù)相關(guān)的可選值做響應(yīng)的操作锨苏。
3疙教、UPDATE
子表父表直接操作都會違反引用完整性約束。兩種解決方法:
先更新子表的引用列為空伞租,再更新父表的主鍵的列的值贞谓,然后把子表的引用列更新成新的父表的值;
使用ON DELETE SET NULL葵诈,先更新父表裸弦,然后將子表外鍵為空的記錄更新為新的值。
4作喘、DDL語句
DROP TABLE與TRUNCATE TABLE理疙,操作父表,違反引用完整性約束泞坦,子表則不然
一般兩個表如果有關(guān)聯(lián)關(guān)系窖贤,就會把主表(一)的主鍵作為從表(多)的外鍵
創(chuàng)建從表之前必須保證主表存在,否則先創(chuàng)建主表。
刪除表的時(shí)候先刪除從表才能刪除主表
六赃梧、總結(jié)
- 兩個表引擎必須為InnoDB滤蝠,MyISAM不支持
- 外鍵參照必須建立索引(必須是主鍵、唯一)授嘀,MySQL如果沒有會自動創(chuàng)建,SQL標(biāo)準(zhǔn)中必須是唯一,但Mysql對他進(jìn)行了擴(kuò)展,不必是唯一(實(shí)戰(zhàn)開發(fā)中一般使用父表的主鍵作為子表的外鍵),
- 在子表上創(chuàng)建外鍵約束
- 外鍵關(guān)系的兩個表的列必須是數(shù)據(jù)類型相似(建議保持相同)物咳,也就是可以相互轉(zhuǎn)換類型的列,比如int和tinyint可以蹄皱,而int和char則不可以览闰;
- 外鍵的組合列不能超過32列
- 子表和父表必須在同一個數(shù)據(jù)庫。分布式數(shù)據(jù)庫中巷折,外鍵不能跨節(jié)點(diǎn)压鉴,但觸發(fā)器可以你不能在CREATE TABLE語句中包含AS子查詢子句定義一個外鍵約束。相反盔几,你必須創(chuàng)建一個沒有約束的表晴弃,然后添加ALTER TABLE語句