在建表的時候時候,可以對於刪除delete、修改update設置為級聯。用一個例子先說明外鍵級聯級聯的概念
假如數據庫中本以存在一張usertable如下:
此user表非常簡單,id為主鍵。
下面我將新建一張cascade_test表如下,這裡的user_id與usertable的主鍵id形成參照完整性,並同時建立刪除與修改的級聯:
如果用SQL語句建立上圖的表則如下:
CREATE TABLE `test`.`cascade_test` ( `id` INTEGER UNSIGNED NOT NULL auto_increment, `content` TEXT, `user_id` INTEGER UNSIGNED, -- 由於usertable的主鍵是INTEGER UNSIGNED,這裡必須同為這樣類型,鍵值對應 PRIMARY KEY (`id`), CONSTRAINT `FK_cascade_test_1` FOREIGN KEY `FK_cascade_test_1` (`user_id`) REFERENCES `test`.`usertable`(`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB; -- 數據庫引擎設置,可以沒有比起普通設置外鍵的語句,在其下多出了兩個級聯的聲明,ON DELETE CASCADE、ON UPDATE CASCADE
設置級聯與不設置級聯,在參照完整性上是沒有區別的。
user的id類型是怎麼cascade_test的user_id類型就應該怎麼樣,這裡需要嚴格照抄,由於user的id設置為無符號整形,這裡cascade_test的user_id還不能是整形,一定要特意聲明為無符號整形,否則會出現如下的[Err] 1005 - Can't create table 'xx' (errno: 150),其實150頁就是參照完整性錯誤。
之後,在新建出來的cascade_test插入如下一些數據:
同樣地,由於參照完整性的存在,cascade_test的user_id的取值范圍還需要在user的id現有的值來取。
設置級聯與不設置級聯唯一的區別,就是我們在刪除user的id中數據的同時,同樣會刪除cascade_test的user_id的所有有關字段。修改級聯同樣如此。
比如將user中id為6的項刪除,也就是執行如下的語句:
delete from usertable where id=6
運行效果如下圖:
usertable中id=6的項被刪除是肯定的,
由於刪除級聯的存在:cascade_test中user_id=6的項通通被刪除。
如果不設置級聯,在usertable中id=6的項被刪除的同時,cascade_test中user_id=6的項是不會刪除的。造成了一定參照完整性的缺失。
下面說說級聯的劣勢:
這看來似乎很強大的樣子,尤其是在網頁編程的時候,就不用寫這麼多刪除語句了,僅僅是刪除一個主鍵,就能把所有涉及的項刪除
但是,在你的工程足夠的時候,這樣的刪除會很慢,實質上造成了表與表之間的耦合。遠遠比不刪新增加一個isDel的項,使用標志刪除的方式,查表的時候僅查詢isDel=false的項。其實delete語句在網頁的編程的時間根本就是可以扔掉的。這樣還有個好處,出現在需要找被刪除的舊數據的時候,絕對可以找回來。
這樣你的網頁的運行速度會大大加快,否則如果一旦執行級聯刪除的語句,會涉及的表足夠多的時候,執行起來將會足夠慢。