程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> 【Mysql】外鍵級聯與級聯的劣勢

【Mysql】外鍵級聯與級聯的劣勢

編輯:MySQL綜合教程

【Mysql】外鍵級聯與級聯的劣勢


在建表的時候時候,可以對於刪除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語句在網頁的編程的時間根本就是可以扔掉的。這樣還有個好處,出現在需要找被刪除的舊數據的時候,絕對可以找回來。

這樣你的網頁的運行速度會大大加快,否則如果一旦執行級聯刪除的語句,會涉及的表足夠多的時候,執行起來將會足夠慢。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved