簡介
mysql外來鍵起到約束作用,在資料庫層面保證資料的完整性。例如使用外來鍵的cascade型別,當子表(例如user_info)關聯父表(例如user)時,父表更新或刪除時,子表會更新或刪除記錄,這個過程是資料庫層面完成的。早期企業系統資料庫設計裡面比較多,雖說幫程式設計師節省了delete、update操作,實際上增加了潛規則,也增加了軟體複雜度,也會會減弱效能。
所以在應用程式設計中,我們應盡量在應用層保證資料的完整性(如使用事務處理機制),而不是資料庫層面。
下面對mysql的外來鍵進行介紹。
mysql支援外來鍵的儲存引擎只有innodb,在建立外來鍵的時候,要求父表必須有對應的索引,子表在建立外來鍵的時候也會自動建立對應的索引。在建立索引的時候,可以指定在刪除、更新父表時,對子表進行的相應操作,包括restrict、no action、set null和cascade。
restrict和no action相同,是指在子表有關聯記錄的情況下父表不能更新;
cascade表示父表在更新或者刪除時,更新或者刪除子表對應記錄;
set null則是表示父表在更新或者刪除的時候,子表的對應欄位被set null。
示例因為只有innodb引擎才允許使用外來鍵,所以,我們的資料表必須使用innodb引擎。
建立資料庫:
create database test;
建立兩個表,其中第乙個表的」id」是第二個表(userinfo)的外來鍵:
create table `user` (
`id` int(4) not null,
`***` enum('f','m') default null,
primary key (`id`)
) engine=innodb default charset=utf8;
create table `userinfo` (
`sn` int(4) not null auto_increment,
`userid` int(4) not null,
`info` varchar(20) default null,
primary key (`sn`),
key `userid` (`userid`),
constraint `userinfo_ibfk_1` foreign key (`userid`) references `user` (`id`) on delete cascade on update cascade
) engine=innodb default charset=utf8;
注意:1、儲存引擎必須使用innodb引擎;
2、外來鍵必須建立索引;
3、外來鍵繫結關係這裡使用了「 on delete cascade 」 「on update cascade」,意思是如果外來鍵對應資料被刪除或者更新時,將關聯資料完全刪除或者相應地更新。更多資訊請參考mysql手冊中關於innodb的文件。
好,接著我們再來插入資料測試:
insert into `user` (`id`,`***`)
values ('1', 'f'), ('2', 'm'), ('3', 'f');
insert into `userinfo` (`sn`,`userid`,`info`)
values ('1', '1', '2005054dsf'),
('2', '1', 'fdsfewfdsfds'),
('3', '1', 'gdsgergergrtre'),
('4', '2', 'et34t5435435werwe'),
('5', '2', '435rtgtrhfghfg'),
('6', '2', 'ret345tr4345'),
('7', '3', 'fgbdfvbcbfdgr'),
('8', '3', '45r2343234were'),
('9', '3', 'wfyhtyjtyjyjy');
我們先看一下當前資料表的狀態:
mysql> show tables;
| tables_in_test |
| user |
| userinfo |
2 rows in set (0.00 sec)
user表中的資料:
mysql> select * from user;
| id | *** |
| 1 | f |
| 2 | m |
| 3 | f |
3 rows in set (0.00 sec)
userinfo表中的資料:
mysql> select * from userinfo;
| sn | userid | info |
| 1 | 1 | 2005054dsf |
| 2 | 1 | fdsfewfdsfds |
| 3 | 1 | gdsgergergrtre |
| 4 | 2 | et34t5435435werwe |
| 5 | 2 | 435rtgtrhfghfg |
| 6 | 2 | ret345tr4345 |
| 7 | 3 | fgbdfvbcbfdgr |
| 8 | 3 | 45r2343234were |
| 9 | 3 | wfyhtyjtyjyjy |
9 rows in set (0.00 sec)
對於建立以上不表,相信對大家也沒什麼難度了。好的,下面我們就要試驗我們的級聯刪除功能了。
mysql> delete from `user` where `id`='2';
query ok, 1 row affected (0.03 sec)
mysql> select * from user;
| id | *** |
| 1 | f |
| 3 | f |
2 rows in set (0.00 sec)
再看看userinfo表中已經沒有userid為2的3條資料記錄了,對應資料確實自動刪除了!
mysql> select * from userinfo;
| sn | userid | info |
| 1 | 1 | 2005054dsf |
| 2 | 1 | fdsfewfdsfds |
| 3 | 1 | gdsgergergrtre |
| 7 | 3 | fgbdfvbcbfdgr |
| 8 | 3 | 45r2343234were |
| 9 | 3 | wfyhtyjtyjyjy |
6 rows in set (0.00 sec)
更新的操作也類似,因為我們在前面建表的時候已經定義外來鍵刪除、更新操作都是cascade,所以在這裡可以直接測試資料。
將user表中原來id為1的資料記錄更改為id為4,執行如下:
mysql> update user set id=4 where id='1';
query ok, 1 row affected (0.03 sec)
rows matched: 1 changed: 1 warnings: 0
現在去看看兩個表中是資料是否發生了變化:
mysql> select * from user;
| id | *** |
| 3 | f |
| 4 | f |
2 rows in set (0.00 sec)
mysql> select * from userinfo;
| sn | userid | info |
| 1 | 4 | 2005054dsf |
| 2 | 4 | fdsfewfdsfds |
| 3 | 4 | gdsgergergrtre |
| 7 | 3 | fgbdfvbcbfdgr |
| 8 | 3 | 45r2343234were |
| 9 | 3 | wfyhtyjtyjyjy |
6 rows in set (0.00 sec)
比較原來的表可以發現它們的確已經更新成功了,測試完成!!!這也就實現了用外來鍵對多個相關聯的表做同時刪除、更新的操作,從而保證了資料的一致性。
注意:當使用了外來鍵後,使用truncate命令去清空父表資料時,會提示操作出錯,這時候應該先去刪除字表的資料。
示例部分內容來自:
mysql使用外來鍵實現級聯刪除與更新的方法_mysql_指令碼之家
mysql外來鍵級聯刪除
create table user id int 4 not null,enum f m default null,primary key id engine innodb default charset latin1 create table userinfo sn int 4 not null ...
mysql的外來鍵級聯查詢 mysql外來鍵使用和級聯
如下面的 idint not null auto increment primary key,jobidint not null,studentidint not null,foreign key studentid referencesstudent id foreign key jobid re...
mysql外來鍵級聯更新刪除
mysql支援外來鍵的儲存引擎只有innodb,在建立外來鍵的時候,要求父表必須有對應的索引,子表在建立外來鍵的時候也會自動建立對應的索引。在建立索引的時候,可以指定在刪除 更新父表時,對子表進行的相應操作,包括restrict no action set null和cascade。其中restri...