在本文中,咱們將向讀者詳細介紹如何在更新和刪除父表數據的同時,觸發有關子表數據的級聯更新和刪除操做。您將看到當使用InnoDB表的時候,藉助於外鍵約束就能夠輕鬆搞定這一過程。
1、利用外鍵約束更新並刪除MySQL中的數據html
咱們知道,開發可以維護多個表的完整性的數據庫驅動的應用程序是一件很是複雜的事情——即便應用程序所面對的是當前最流行的開源關係型數據庫管理系統MySQL服務器時也不例外。若是一個應用程序必須處理多個數據庫表,而這些表之間有存在着某些預約義的關係,這時一旦父表中的數據被更新或者刪除,那麼這些變化必須正確反映到子表中,不然就會引起許多問題。python
具體就MySQL來講,在大多數狀況下相似這樣的數據庫完整性問題均可以經過使用程序庫ORM加以解決,不過這並不是解決問題的惟一出路。另外一種解決方案是使用MySQL的InnoDB存儲引擎的外鍵約束。 在使用這個引擎的時候,咱們能夠在父表執行諸如更新和刪除等操做時,讓子表執行指定的動做來進行響應。web
在前一篇文章中,咱們演示了從父表中刪除一篇博客的數據時,如何觸發對存放該博客有關評論的表中相應數據的級聯刪除操做。數據庫
下面咱們仍是之前面的示例來詮釋如何在數據庫層來維護有關的表的完整性,而不是將這項任務讓推給處理數據層的應用程序。django
前面咱們在介紹在MySQL的InnoDB表中應用外鍵約束的時候,都是單獨觸發級聯更新或級聯刪除操做,實際上,當父表的鍵發生同時更新和刪除時,咱們還能夠同時觸發對有關子表的相應操做,這樣更易於維護數據庫的一致性。服務器
下面咱們將對此展開詳細的介紹。性能
2、以級聯方式刪除數據學習
爲了保持連續性,咱們在介紹如何以級聯方式對子表數據進行更新和刪除操做的時候,仍將使用前面所用的示例。在學習新內容以前,讓咱們先來回顧一下當特定的博客文章給刪掉時,如何使用外鍵約束刪除存儲評論的數據表中的有關數據,注意,這裏只涉及到刪除操做。網站
下面是咱們示例中用到的兩個表的定義:ui
DROP TABLE IF EXISTS `test`.`blogs`;
CREATE TABLE `test`.`blogs` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`title` TEXT,
`content` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `test`.`comments`;
CREATE TABLE `test`.`comments` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`blog_id` INT(10) UNSIGNED DEFAULT NULL,
`comment` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `blog_ind` (`blog_id`),
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`blog_id`) REFERENCES `blogs` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
上面的代碼中,咱們定義了兩個簡單的InnoDB表,第一個用於存儲博客數據,第二個用來保存博客的有關評論。很明顯,這兩個表之間存在着一對多的關係,這正好能夠用來演示外鍵約束的好處。如今,給咱們的表填充以下所示的數據:
INSERT INTO blogs (id, title, content, author) VALUES (NULL,'Title of the first blog entry', 'Content of the first blog entry', 'Tom')
INSERT INTO comments (id, blog_id, comment, author) VALUES (NULL, 1, 'Commenting first blog entry', 'Susan Norton'), (NULL, 1, 'Commenting first blog entry', 'Rose')
好了,如今表中已經有數據了。可是,如何在應用程序層次以外刪除blogs表的第一個數據項呢?實際上這很簡單,以下所示的命令便可辦到:
DELETE FROM blogs WHERE id = 1
若是咱們定義一個簡單的外鍵約束,那麼上述的DELETE命令不只會刪除第一篇博客,並且與之相關的全部評論也會隨之清空,而且這一過程只需一步便可搞定,呵呵,聽起來不錯吧。
然而,就像本文前面所說過的那樣,InnoDB存儲引擎還容許同時執行級聯更新和刪除這兩種操做,下面咱們會爲讀者詳細介紹。
3、擴展外鍵約束的用途
如今是介紹在父表數據刪除時如何對子表中的有關數據進行級聯更新和刪除的時候了,這可以有效簡化處理這些表的應用程序的邏輯實現。
爲了幫您更好地理解InnoDB存儲引擎提供的這一特性,咱們將經過示例加以說明。如今,咱們從新定義以前見過的那兩個表,並規定特定博客被更新和刪除時,要對錶comments執行相應的級聯動做。下面給出這兩個表的定義:
DROP TABLE IF EXISTS `test`.`blogs`;
CREATE TABLE `test`.`blogs` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`title` TEXT,
`content` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `test`.`comments`;
CREATE TABLE `test`.`comments` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`blog_id` INT(10) UNSIGNED DEFAULT NULL,
`comment` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `blog_ind` (`blog_id`),
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`blog_id`) REFERENCES `blogs` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
如上所示,定義的第一個表blog與前面的相同,咱們只需注意一下第二個表就好了。本例中,表comments的字段保持不變,不一樣之處在於,此次它包含了以下所示的SQL語句:
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`blog_id`) REFERENCES `blogs` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
固然,這是負責博客更新和刪除時,對其有關的評論進行級聯更新和刪除的。
咱們已經給外鍵blog_id指定了約束,如今上述的兩個表之間的關係的完整性就能夠徹底在數據庫級別來處理了,固然,在一些應用程序的性能方面可能會有些損失。下面咱們將介紹如何輕鬆完成此項任務。
4、外鍵約束的實際例子
前面,咱們已經定義了兩個IndoDB表,並將其做爲博客應用程序的構造塊。如今,咱們要作的是,每當有博客更新和刪除時,同時更新和刪除博客對應的全部評論。
咱們將經過具體的代碼加以演示。 所以,假設存儲在blogs表中的惟一的博客數據須要更新,那麼有關評論也得同時更新,這時咱們能夠經過一個UPDATE語句來完成這一任務,代碼以下所示:
UPDATE blogs SET id = 2, title = 'Title of the first blog entry', content = 'Content of the first blog entry', author = 'John Doe' WHERE id = 1
您可能猜到了,對第一個博客數據項的更新將自動地引發與該博客有關的評論的更新。如今,讓咱們利用以下所示的SQL查詢來刪除博客:
DELETE FROM blogs WHERE id = 2
這時,MySQL會替咱們刪除有關的評論。如今,咱們已經看到了外鍵約束在維護多個表的關係的一致性方面給咱們帶來的幫助。是否是很方便呀?還等什麼,您也動手試一試吧!
5、小結
在本文中,咱們爲向讀者詳細介紹瞭如何在更新和刪除父表數據的同時,觸發有關子表數據的級聯更新和刪除操做。如您所見,當使用InnoDB表的時候,藉助於外鍵約束就能夠輕鬆搞定這一過程。
須要說明的是,到目前爲止,對示例數據庫表的操做,他們都是手工經過SQL命令進行的,然而,在基於web的環境中,則須要利用某種服務器端語言來跟MySQL打交道。其中,PHP就是一個不錯的選擇,因此,咱們將在下一篇文章中討論如何經過PHP 5使用外鍵約束。
Django數據模型、ER圖、級聯操做
-
Django模型的Field Types總結 - Devil_2009的專欄 - 博客頻道 - CSDN.NET
-
理解django的多對多ManyToManyField - MWI - ITeye技術網站
-
Navicat11全系列激活(註冊機) - 簡書
-
navicat 自定義查看某幾個表的ER圖 與導出表結構 - QueenJade的收錄 - 博客頻道 - CSDN.NET
-
Django模型中的OneToOneField和ForeignKey有什麼區別_百度知道
-
菜鳥 django ForeignKey 求教 - Python社區
-
Model field reference | Django documentation | Django
-
玩轉MySQL中的外鍵約束之更新和刪除-admin126com-ChinaUnix博客
-
MySQL中利用外鍵實現級聯刪除、更新 - dodott的專欄 - 博客頻道 - CSDN.NET