2/28/2012

星期二, 2月 28, 2012
在 挑戰Dreamweaver CS4互動網站百寶箱--使用PHP
http://www.e-happy.com.tw/indexbookshow.asp?bid=175
一書的第十章網站部落格程式,有讀者問到如何在刪除分類時,可以一併刪除分類中的文章,再一併刪除每一篇文章的留言呢?
我們在書上第10-43~10-45頁有達到刪除分類時,一併刪除分類中的文章,但是沒有刪除每一篇文章的留言。在過去PHP的開發方式中,其實這個完成的方式有其一定的困難度,原因是如果要刪除每一篇文章的留言,要利用迴圈先調出每一篇文章刪除留言後,再刪除文章,再刪除分類!

不過在MySQL5支援關聯式資料庫的 foregin key 功能後,這個刪除關聯式資料庫的動作就可以不用寫程式,直接由MySQL資料庫中設定即可達成,以下是茶米完整的說明:

一、了解目前問題的所在

原來資料庫的關聯

原來的資料庫中的規劃,是由 blogcategory 分類資料表以 ca_id 與 blogmessages 文章資料表關聯,而 blogmessages 文章資料表以 blog_id 再與 blogcomments 資料表關聯。
那目前的問題不在於刪除 blogcategory 中的資料時再刪除關聯的 blogmessages 中的資料,也不在於刪除 blogmessages 時再刪除 blogcomments 中關聯的資料,而是刪除 blogcategory 時一併刪除 blogmessages 中關聯的資料,也一併刪除 blogcomments 中的資料。

二、設定MySQL資料庫的 foregin key

茶米先不說些深的大道理,你一定會問:支援 foregin key 的資料庫有什麼好處?其實以目前的範例來說,它的好處就是可以維持資料庫的完整性,再白話一點的意思,就是如果有關鍵的資料表,在 A 中刪除了一筆資料,B 裡相關的資料就會一併被刪除!所以設定 foregin key 即可完成我們目前這個範例的需求。

MySQL 的資料表如果要支援 foregin key 有幾個要點:
MySQL 的版本要在 5.1.X 以上 (好像啦.....)
資料庫的類型必須是 innoDB

我們書上的範例,剛好都符合這二個要點喔!所以可以馬上著手!以下我們就要教您如何在 phpMyAdmin 中設定資料表之間的 foregin key。
進入phpMyAdmin 之後,我們要由關聯最底層的 blogcomments 留言資料表的 blog_id (此欄為 foregin key) 與 blogmessage 的主索引 blog_id 設定關聯並建立資料的完整性。
要注意的是,要建立 foregin key 的欄位必須要建立索引,方式如下,這裡以 blogcomments 留言資料表的 blog_id為例 :




接著要建立 blogcomments 留言資料表的 blog_id (此欄為 foregin key) 與 blogmessage 的主索引 blog_id 設定關聯並建立資料的完整性。




當關聯父資料表的主鍵紀錄行被刪除或修改時,InnoDB 對子資料表中紀錄行的處理方式:
CASCADE - 會將有所關聯的紀錄行也會進行刪除或修改。
SET NULL - 會將有所關聯的紀錄行設定成 NULL。
NO ACTION - 有存在的關聯紀錄行時,會禁止父資料表的刪除或修改動作。
RESTRICT - 與 NO ACTION 相同。
接著要往上一層,建立 blogmessages 文章資料表的 ca_id 為 foregin key 與 blogcategory 的 ca_id 建立關聯並設定資料完整性:








如此即完成關聯的設定!

三、測試設定完的結果

接著回到範例,現在其實不修改程式,因為剛才資料庫的修改,也能達到刪除一個分類,就能刪除該分類的文章及每篇文章的留言。

但是為了讓讀者能更清楚看到結果,請開啟 到原始碼,這個頁面中加入 2 個刪除指令,用來刪除 blogcategory 的分類以及 blogmessages 的文章,現在我們要將刪除 blogmessages 的動作拿掉,只刪除 blogcategory 的分類,看資料庫會不會自動刪除其他 2 個資料表中的資料。
請將刪除 blogmessages 文章的程式 mark 起來:



存檔後我們來檢視結果,我們可以看到這個分類除了有文章,每篇文章還有留言:


進入管理界面後我們刪除這個分類:


我們進入 phpMyAdmin 來審視結果:





測試的結果,相關資料表中的相關記錄果然都自動刪除了!是不是很神奇呢?快點試看看吧!

0 意見 :

張貼留言