USE `wfc_database`; # 主表(也能夠稱做:被參照表、referenced table、outTable) ALTER TABLE `app` ENGINE=INNODB; # 從表(也能夠稱做:參照表、外表、referencing table ) ALTER TABLE `app_version` ENGINE=INNODB; # 一個 【應用 】能夠有多個【應用版本】 # 所以 app 和 app_version 是 1:n 的關係 (一個 app_id 對應有多個 av_app_id) # app_id是 app表 的主鍵, av_app_id是 app_version表 的索引 # app_version數據訂正(在 app_version表中刪除 app已經沒有的 app_id) DELETE FROM `app_version` WHERE av_app_id NOT IN ( SELECT app_id FROM app); # 此步驟極爲重要,不然沒法添加外鍵(從表中存在主表中沒有的外鍵id是不容許的) # app_version添加外鍵 ALTER TABLE `app_version` ADD CONSTRAINT fk_av_app_id FOREIGN KEY (av_app_id) REFERENCES `app` (app_id) ON DELETE CASCADE ON UPDATE CASCADE; # 創建外鍵的前提: 被約束字段與外鍵的數據類型必須相同 被約束字段須要設置爲索引,外鍵須要設置爲 PRIMARY 外鍵做用: 使兩張表造成關聯,外鍵只能引用從表中的列的值! 指定從表關鍵字: foreign key (列名) 引用外鍵關鍵字: references <外鍵表名> (外鍵列名) # 事件觸發(級聯操做)限制 : on delete 和 on update 可設參數 cascade (跟隨外鍵改動) ,強烈推薦,可以保存數據一致性 restrict (限制主表中的外鍵改動) [默認] no action # 若是以上語句在建立過程當中有報以下錯誤 Can not create table 'd91.#sql-197e_18b4' (errno: 150) # 請把 av_app_id 和 app_id 的字段類型設置爲徹底相同 也就是約束字段的 類型、長度、有無符號、是否爲空、默認值 要設置跟外鍵相同 對於此次的場景,我把 app_id 和 av_app_id 都設置爲 INT(10) , UNSIGNED,NOT NULL 確保外鍵的名字沒有和已經存在的 鍵值/索引名 重名 # 補充,若是要刪除外鍵約束能夠這麼作 alter table 表名 drop foreign key 外鍵約束名稱; # 好比,要刪掉剛剛建立的外鍵,你能夠 ALTER TABLE `app_version` DROP FOREIGN KEY fk_av_app_id ; # --------------------- InnoDB外鍵知識 ------------------------- # 方法一: 定義數據表 假如某個電腦生產商,它的數據庫中保存着整機和配件的產品信息。用來保存整機產品信息的表叫作 Pc;用來保存配件供貨信息的表叫作Parts。 在Pc表中有一個字段,用來描述這款電腦所使用的CPU型號; 在Parts 表中相應有一個字段,描述的正是CPU的型號,咱們能夠把它想成是所有CPU的型號列表。 很顯然,這個廠家生產的電腦,其使用的CPU必定是供貨信息表(parts)中存在的型號。這時,兩個表中就存在一種約束關係(constraint)——Pc表中的CPU型號受到Parts 表中型號的約束。 首先咱們來建立 parts 表: CREATE TABLE parts ( ... 字段定義 ..., model VARCHAR(20) NOT NULL, ... 字段定義 ... ); 接下來是Pc表: CREATE TABLE pc ( ... 字段定義 ..., cpumodel VARCHAR(20) NOT NULL, ... 字段定義 ... }; 設置索引 若要設置MySQL外鍵,在 參照表 [外表] (referencing table,即Pc表) 和被參照表 [主表] (referenced table,即parts表) 中,相對應的兩個字段必須都設置索引(index)。 對Parts表: ALTER TABLE parts ADD INDEX idx_model (model); 這句話的意思是,爲 parts 表增長一個索引,索引創建在 model 字段上,給這個索引發個名字叫idx_model。 對Pc表也相似: ALTER TABLE pc ADD INDEX idx_cpumodel (cpumodel); 事實上這兩個索引能夠在建立表的時候就設置。這裏只是爲了突出其必要性。 定義外鍵 下面爲兩張表之間創建前面所述的那種「約束」。由於pc的CPU型號必須參照parts表中的相應型號,因此咱們將Pc表的cpumodel字段設置爲「外鍵」(FOREIGN KEY),即這個鍵的參照值來自於其餘表。 ALTER TABLE pc ADD CONSTRAINT fk_cpu_model FOREIGN KEY (cpumodel) REFERENCES parts(model); 第一行是說要爲Pc表設置MySQL外鍵,給這個外鍵起一個名字叫作fk_cpu_model;第二行是說將本表的cpumodel字段設置爲外鍵;第三行是說這個外鍵受到的約束來自於Parts表的model字段。 這樣,咱們的外鍵就能夠了。若是咱們試着CREATE一臺Pc,它所使用的CPU的型號是Parts表中不存在的,那麼MySQL會禁止這臺PC被CREATE出來。 級聯操做 考慮如下這種狀況: 技術人員發現,一個月以前輸入到 parts 表中的某個系列的 cpu (可能有不少款)的型號全都輸錯了一個字母,如今須要改正。咱們但願的是,當 parts 表中那些 Referenced Column 有所變化時,相應表中的 Referencing Column 也能自動更正。 能夠在定義MySQL外鍵的時候,在最後加入這樣的關鍵字: ON UPDATE CASCADE; 即在主表更新時,子表(們)產生連鎖更新動做,彷佛有些人喜歡把這個叫「級聯」操做。:) 若是把這語句完整的寫出來,就是: # 例子一 ALTER TABLE pc ADD CONSTRAINT fk_cpu_model FOREIGN KEY (cpumodel) REFERENCES parts(model) ON UPDATE CASCADE; 除了 CASCADE 外,還有 RESTRICT(禁止主表變動)、SET NULL(子表相應字段設置爲空)等操做。 延伸閱讀 外鍵(Foreign Key) 若是公共關鍵字在一個關係中是主關鍵字,那麼這個公共關鍵字被稱爲另外一個關係的外鍵。因而可知,外鍵表示了兩個關係之間的聯繫。以另外一個關係的外鍵做主關鍵字的表被稱爲主表,具備此外鍵的表被稱爲主表的從表。外鍵又稱做外關鍵字。 外鍵的做用: 保持數據一致性,完整性,主要目的是控制存儲在外鍵表中的數據。 使兩張表造成關聯,外鍵只能引用外表中的列的值! 方法二: 創建外鍵的前提: 本表的列必須與外鍵類型相同(外鍵必須是外表主鍵)。 外鍵做用: 使兩張表造成關聯,外鍵只能引用外表中的列的值! 指定主鍵關鍵字: foreign key(列名) 引用外鍵關鍵字: references <外鍵表名>(外鍵列名) 事件觸發限制: on delete和on update , 可設參數cascade(跟隨外鍵改動), restrict(限制外表中的外鍵改動),set Null(設空值),set Default(設默認值),[默認]no action 例如: outTable表 主鍵 id 類型 int 建立含有外鍵的表: create table temp( id int, name char(20), foreign key(id) references outTable(id) on delete cascade on update cascade); 建立後修改表: alter table temp add constraint foreign key(id) references outTable(id) on delete cascade on update cascade; 說明:把id列設爲外鍵,參照外表outTable的id列,當外鍵的值刪除本表中對應的列刪除;當外鍵的值改變本表中對應的列值改變。在使用alter中constraint是針對使用外鍵的狀況。 這種主外鍵的級聯操做在mysql中只支持InnoDB類型。要設置爲該類型要在mysql中的配置文件中改動默認不支持InnoDB爲支持,可輸入命令查看是否支持: mysql > show variables like "have%"; 若是不支持中止mysql,打開my.ini配置文件找到skip-innodb,前面加#,重啓mysql,而後修改主外鍵兩表類型: mysql > alter table xxx ENGINE = InnoDB; 最後在命令中輸入上述建立外鍵的方法。 不過,若是你的業務不須要使用到事務,那麼使用myisam是最佳考慮, 由於myisam不支持事務,有比較好的性能。 可是若是你的業務必需要使用到事務,也就是說對數據一致性要求很高的話,須要使用到INODB,因爲INODB要使用到鎖,所以它的併發能力就差一些,所以性能方面也會差一些。 若是要刪除外鍵約束可以使用以下命令: mysql > alter table ss_accesscode drop foreign key 外鍵約束名稱; 注:添加外鍵約束時若沒有指定外鍵約束的名稱,則系統會自動添加外鍵約束名:表名_ibfk_n(表示第n個外鍵約束)。好比咱們建立外鍵時就省略了外鍵線束名稱。