【Python】Django數據模型、級聯刪除、級聯更新、ER圖導出等


在本文中,我們將向讀者詳細介紹如何在更新和刪除父表數據的同時,觸發有關子表數據的級聯更新和刪除操作。您將看到當使用InnoDB表的時候,借助於外鍵約束就可以輕松搞定這一過程。

  一、利用外鍵約束更新並刪除MySQL中的數據

  我們知道,開發能夠維護多個表的完整性的數據庫驅動的應用程序是一件非常復雜的事情——即使應用程序所面對的是當前最流行的開源關系型數據庫管理系統MySQL服務器時也不例外。如果一個應用程序必須處理多個數據庫表,而這些表之間有存在着某些預定義的關系,這時一旦父表中的數據被更新或者刪除,那么這些變化必須正確反映到子表中,否則就會引發許多問題。

  具體就MySQL來說,在大多數情況下類似這樣的數據庫完整性問題都可以通過使用程序庫ORM加以解決,不過這並非解決問題的唯一出路。另一種解決方案是使用MySQL的InnoDB存儲引擎的外鍵約束。 在使用這個引擎的時候,我們可以在父表執行諸如更新和刪除等操作時,讓子表執行指定的動作來進行響應。

  在前一篇文章中,我們演示了從父表中刪除一篇博客的數據時,如何觸發對存放該博客有關評論的表中相應數據的級聯刪除操作。

  下面我們還是以前面的示例來詮釋如何在數據庫層來維護有關的表的完整性,而不是將這項任務讓推給處理數據層的應用程序。

  前面我們在介紹在MySQL的InnoDB表中應用外鍵約束的時候,都是單獨觸發級聯更新或級聯刪除操作,實際上,當父表的鍵發生同時更新和刪除時,我們還可以同時觸發對有關子表的相應操作,這樣更易於維護數據庫的一致性。

  下面我們將對此展開詳細的介紹。

  二、以級聯方式刪除數據

  為了保持連續性,我們在介紹如何以級聯方式對子表數據進行更新和刪除操作的時候,仍將使用前面所用的示例。在學習新內容之前,讓我們先來回顧一下當特定的博客文章給刪掉時,如何使用外鍵約束刪除存儲評論的數據表中的有關數據,注意,這里只涉及到刪除操作。

  下面是我們示例中用到的兩個表的定義:

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存儲引擎還允許同時執行級聯更新和刪除這兩種操作,下面我們會為讀者詳細介紹。

 

  三、擴展外鍵約束的用途

  現在是介紹在父表數據刪除時如何對子表中的有關數據進行級聯更新和刪除的時候了,這能夠有效簡化處理這些表的應用程序的邏輯實現。

  為了幫您更好地理解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指定了約束,現在上述的兩個表之間的關系的完整性就可以完全在數據庫級別來處理了,當然,在一些應用程序的性能方面可能會有些損失。下面我們將介紹如何輕松完成此項任務。

 

  四、外鍵約束的實際例子

  前面,我們已經定義了兩個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會替我們刪除有關的評論。現在,我們已經看到了外鍵約束在維護多個表的關系的一致性方面給我們帶來的幫助。是不是很方便呀?還等什么,您也動手試一試吧!

  五、小結

  在本文中,我們為向讀者詳細介紹了如何在更新和刪除父表數據的同時,觸發有關子表數據的級聯更新和刪除操作。如您所見,當使用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM