mysql支持外鍵。在MySQL中,外鍵主要用來(lái)建立主表與從表的關(guān)聯(lián)關(guān)系,可以為兩個(gè)表的數(shù)據(jù)建立連接,約束兩個(gè)表中數(shù)據(jù)的一致性和完整性;當(dāng)主表刪除某條記錄時(shí),從表中與之對(duì)應(yīng)的記錄也必須有相應(yīng)的改變。一個(gè)表可以有一個(gè)或多個(gè)外鍵,外鍵可以為空值,若不為空值,則每一個(gè)外鍵的值必須等于主表中主鍵的某個(gè)值;且外鍵中列的數(shù)目和對(duì)應(yīng)數(shù)據(jù)類型必須和主表的主鍵中的相同。
本教程操作環(huán)境:windows7系統(tǒng)、mysql8版本、Dell G3電腦。
mysql支持外鍵。
MySQL外鍵(FOREIGN KEY)
外鍵是指定表中與另一個(gè)表的另一個(gè)字段匹配的字段。外鍵對(duì)相關(guān)表中的數(shù)據(jù)設(shè)置了約束,這使MySQL能夠保持參照完整性。
外鍵用來(lái)建立主表與從表的關(guān)聯(lián)關(guān)系,為兩個(gè)表的數(shù)據(jù)建立連接,約束兩個(gè)表中數(shù)據(jù)的一致性和完整性。
對(duì)于兩個(gè)具有關(guān)聯(lián)關(guān)系的表而言,相關(guān)聯(lián)字段中主鍵所在的表就是主表(父表),外鍵所在的表就是從表(子表)。
主表刪除某條記錄時(shí),從表中與之對(duì)應(yīng)的記錄也必須有相應(yīng)的改變。一個(gè)表可以有一個(gè)或多個(gè)外鍵,外鍵可以為空值,若不為空值,則每一個(gè)外鍵的值必須等于主表中主鍵的某個(gè)值。
我們來(lái)看看示例數(shù)據(jù)庫(kù)中的以下數(shù)據(jù)庫(kù)圖。
我們有兩個(gè)表:customers和orders,?每個(gè)客戶都有零個(gè)或多個(gè)訂單,每個(gè)訂單只能屬于一個(gè)客戶。customers表和orders表之間的關(guān)系是一對(duì)多的,它orders由customerNumber字段指定的表中的外鍵建立。customers表中的customerNumber字段與orders表中的customerNumber主鍵字段相關(guān) 。
customers?表稱為父表或引用表,orders表稱為子表或引用表。
外鍵可以是一個(gè)列或一組列。子表中的列通常引用父表中的主鍵列。
表可以具有多個(gè)外鍵,子表中的每個(gè)外鍵可以引用不同的父表。
子表中的行必須包含父表中存在的值,例如,orders表中的每個(gè)訂單記錄必須具有customers表customerNumber中存在的值。因此,多個(gè)訂單可以引用同一個(gè)客戶,這種關(guān)系稱為一個(gè)(客戶)到多個(gè)(訂單)或一對(duì)多。
有時(shí),子表和父表是相同的。外鍵引用表的主鍵,例如,下employees表:
reportTo列是一個(gè)外鍵,它引用employeeNumber作為employees表的主鍵的列,以反映員工之間的匯報(bào)結(jié)構(gòu),即每個(gè)員工向另一個(gè)員工匯報(bào),員工可以有零個(gè)或多個(gè)直接匯報(bào)。我們有一個(gè)關(guān)于自聯(lián)接教程可以幫助您根據(jù)這種表查詢數(shù)據(jù)。
reportTo外鍵也被稱為遞歸或自引用的外鍵。
外鍵強(qiáng)制執(zhí)行引用完整性,可幫助您自動(dòng)維護(hù)數(shù)據(jù)的一致性和完整性。例如,您無(wú)法為不存在的客戶創(chuàng)建訂單。
此外,您可以customerNumber在外鍵的刪除操作上設(shè)置級(jí)聯(lián),以便在刪除customers表中的客戶時(shí),也會(huì)刪除與客戶關(guān)聯(lián)的所有訂單。這節(jié)省了使用多個(gè)DELETE語(yǔ)句 或DELETE JOIN語(yǔ)句的時(shí)間和精力。
與刪除相同,您還可以在更新操作上為customerNumber外鍵定義級(jí)聯(lián),以便在不使用多個(gè)UPDATE語(yǔ)句或UPDATE JOIN語(yǔ)句的情況下執(zhí)行跨表更新。
注意:在MySQL中,InnoDB 存儲(chǔ)引擎支持外鍵,因此您必須創(chuàng)建InnoDB表才能使用外鍵約束。
mysql定義外鍵時(shí),需要遵守下列規(guī)則:
-
主表必須已經(jīng)存在于數(shù)據(jù)庫(kù)中,或者是當(dāng)前正在創(chuàng)建的表。如果是后一種情況,則主表與從表是同一個(gè)表,這樣的表稱為自參照表,這種結(jié)構(gòu)稱為自參照完整性。
-
必須為主表定義主鍵。
-
主鍵不能包含空值,但允許在外鍵中出現(xiàn)空值。也就是說(shuō),只要外鍵的每個(gè)非空值出現(xiàn)在指定的主鍵中,這個(gè)外鍵的內(nèi)容就是正確的。
-
在主表的表名后面指定列名或列名的組合。這個(gè)列或列的組合必須是主表的主鍵或候選鍵。
-
外鍵中列的數(shù)目必須和主表的主鍵中列的數(shù)目相同。
-
外鍵中列的數(shù)據(jù)類型必須和主表主鍵中對(duì)應(yīng)列的數(shù)據(jù)類型相同。
為表創(chuàng)建外鍵
MySQL創(chuàng)建外鍵語(yǔ)法
以下語(yǔ)法說(shuō)明如何在CREATE TABLE語(yǔ)句中的子表中定義外鍵。
CONSTRAINT?constraint_name FOREIGN?KEY?foreign_key_name?(columns) REFERENCES?parent_table(columns) ON?DELETE?action ON?UPDATE?action
讓我們更詳細(xì)地學(xué)習(xí)一下語(yǔ)法:
-
CONSTRAINT子句允許您為外鍵約束定義約束名稱。如果省略它,MySQL將自動(dòng)生成一個(gè)名稱。
-
FOREIGN KEY子句指定子表中引用父表中主鍵列的列。你可以把一個(gè)外鍵名稱放在FOREIGN KEY子句之后,或者讓MySQL為你創(chuàng)建一個(gè)名字。請(qǐng)注意,MySQL會(huì)自動(dòng)使用foreign_key_name名稱創(chuàng)建索引。
-
REFERENCES子句指定子表中的列所引用的父表及列。在規(guī)定的子表和父表的列數(shù)FOREIGN KEY和REFERENCES必須相同。
-
ON DELETE子句允許您定義刪除父表中的記錄時(shí)子表中記錄的內(nèi)容。如果省略O(shè)N DELETE子句并刪除父表中包含子表中記錄的記錄,MySQL將拒絕刪除。此外,MySQL還為您提供操作,以便您可以使用其他選項(xiàng),例如ON DELETE CASCADE? ,要求MySQL刪除子表中的記錄,當(dāng)父表中的記錄被刪除時(shí),記錄將引用父表中的記錄。如果您不希望刪除子表中的相關(guān)記錄,請(qǐng)改用ON DELETE SET NULL操作。MySQL會(huì)將子表中的外鍵列值設(shè)置為NULL刪除父表中的記錄時(shí),條件是子表中的外鍵列必須接受NULL值。請(qǐng)注意,如果您使用ON DELETE NO ACTION或ON DELETE RESTRICT操作,MySQL將拒絕刪除。
-
ON UPDATE子句使您可以指定更新父表中的行時(shí)子表中的行會(huì)發(fā)生什么。您可以省略O(shè)N UPDATE子句,以便在更新父表中的行時(shí)讓MySQL拒絕對(duì)子表中行的任何更新。ON UPDATE CASCADE操作允許您執(zhí)行跨表更新,并且當(dāng)更新父表ON UPDATE SET NULL中的行時(shí),操作會(huì)將子表中的行中的值重置為值NULL。ON UPDATE NO ACTION或UPDATE RESTRICT行動(dòng)拒絕任何更新。
MySQL創(chuàng)建表外鍵示例
下面的示例創(chuàng)建一個(gè)dbdemo數(shù)據(jù)庫(kù)和兩個(gè)表:categories和? products.每個(gè)類別具有一個(gè)或多個(gè)產(chǎn)品和每個(gè)產(chǎn)品只屬于一個(gè)類別。products表中的cat_id字段被定義為帶有UPDATE ON CASCADE和DELETE ON RESTRICT操作的外鍵。
CREATE?DATABASE?IF?NOT?EXISTS?dbdemo; ? USE?dbdemo; ? CREATE?TABLE?categories( ???cat_id?int?not?null?auto_increment?primary?key, ???cat_name?varchar(255)?not?null, ???cat_description?text )?ENGINE=InnoDB; ? CREATE?TABLE?products( ???prd_id?int?not?null?auto_increment?primary?key, ???prd_name?varchar(355)?not?null, ???prd_price?decimal, ???cat_id?int?not?null, ???FOREIGN?KEY?fk_cat(cat_id) ???REFERENCES?categories(cat_id) ???ON?UPDATE?CASCADE ???ON?DELETE?RESTRICT )ENGINE=InnoDB;
將外鍵添加到表中
MySQL添加外鍵語(yǔ)法
要將外鍵添加到現(xiàn)有表,請(qǐng)使用帶有上述外鍵定義語(yǔ)法的ALTER TABLE語(yǔ)句:
ALTER?TABLE?table_name ADD?CONSTRAINT?constraint_name FOREIGN?KEY?foreign_key_name(columns) REFERENCES?parent_table(columns) ON?DELETE?action ON?UPDATE?action;
MySQL添加外鍵示例
現(xiàn)在,讓我們添加一個(gè)名為vendors的新表,并更改products表以包含供應(yīng)商ID字段:
USE?dbdemo; ? CREATE?TABLE?vendors( ????vdr_id?int?not?null?auto_increment?primary?key, ????vdr_name?varchar(255) )ENGINE=InnoDB; ? ALTER?TABLE?products? ADD?COLUMN?vdr_id?int?not?null?AFTER?cat_id;
要向表中添加外鍵products,請(qǐng)使用以下語(yǔ)句:
ALTER?TABLE?products ADD?FOREIGN?KEY?fk_vendor(vdr_id) REFERENCES?vendors(vdr_id) ON?DELETE?NO?ACTION ON?UPDATE?CASCADE;
現(xiàn)在,products表有兩個(gè)外鍵,一個(gè)引用categories表,另一個(gè)引用vendors表。
【相關(guān)推薦:mysql視頻教程】