


MySQL中的外鍵約束之更新和刪除
一、利用外鍵約束更新并刪除MySQL中的數(shù)據(jù)
我們知道,開發(fā)能夠維護(hù)多個(gè)表的完整性的數(shù)據(jù)庫(kù)驅(qū)動(dòng)的應(yīng)用程序是一件非常復(fù)雜的事情——即使應(yīng)用程序所面對(duì)的是當(dāng)前最流行的開源關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng) MySQL服務(wù)器時(shí)也不例外。如果一個(gè)應(yīng)用程序必須處理多個(gè)數(shù)據(jù)庫(kù)表,而這些表之間有存在著某些預(yù)定義的關(guān)系,這時(shí)一旦父表中的數(shù)據(jù)被更新或者刪除,那么 這些變化必須正確反映到子表中,否則就會(huì)引發(fā)許多問題。
具體就MySQL來說,在大多數(shù)情況下類似這樣的數(shù)據(jù)庫(kù)完整性問題都可以通過使 用程序庫(kù)ORM加以解決,不過這并非解決問題的唯一出路。另一種解決方案是使用MySQL的InnoDB存儲(chǔ)引擎的外鍵約束。 在使用這個(gè)引擎的時(shí)候,我們可以在父表執(zhí)行諸如更新和刪除等操作時(shí),讓子表執(zhí)行指定的動(dòng)作來進(jìn)行響應(yīng)。
在前一篇文章中,我們演示了從父表中刪除一篇博客的數(shù)據(jù)時(shí),如何觸發(fā)對(duì)存放該博客有關(guān)評(píng)論的表中相應(yīng)數(shù)據(jù)的級(jí)聯(lián)刪除操作。
下面我們還是以前面的示例來詮釋如何在數(shù)據(jù)庫(kù)層來維護(hù)有關(guān)的表的完整性,而不是將這項(xiàng)任務(wù)讓推給處理數(shù)據(jù)層的應(yīng)用程序。
前面我們?cè)诮榻B在MySQL的InnoDB表中應(yīng)用外鍵約束的時(shí)候,都是單獨(dú)觸發(fā)級(jí)聯(lián)更新或級(jí)聯(lián)刪除操作,實(shí)際上,當(dāng)父表的鍵發(fā)生同時(shí)更新和刪除時(shí),我們還可以同時(shí)觸發(fā)對(duì)有關(guān)子表的相應(yīng)操作,這樣更易于維護(hù)數(shù)據(jù)庫(kù)的一致性。
下面我們將對(duì)此展開詳細(xì)的介紹。
二、以級(jí)聯(lián)方式刪除數(shù)據(jù)
為了保持連續(xù)性,我們?cè)诮榻B如何以級(jí)聯(lián)方式對(duì)子表數(shù)據(jù)進(jìn)行更新和刪除操作的時(shí)候,仍將使用前面所用的示例。在學(xué)習(xí)新內(nèi)容之前,讓我們先來回顧一下當(dāng)特定的博客文章給刪掉時(shí),如何使用外鍵約束刪除存儲(chǔ)評(píng)論的數(shù)據(jù)表中的有關(guān)數(shù)據(jù),注意,這里只涉及到刪除操作。
下面是我們示例中用到的兩個(gè)表的定義:
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;
上面的代碼中,我們定義了兩個(gè)簡(jiǎn)單的InnoDB表,第一個(gè)用于存儲(chǔ)博客數(shù)據(jù),第二個(gè)用來保存博客的有關(guān)評(píng)論。很明顯,這兩個(gè)表之間存在著一對(duì)多的關(guān)系,這正好可以用來演示外鍵約束的好處。現(xiàn)在,給我們的表填充如下所示的數(shù)據(jù):
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')
好了,現(xiàn)在表中已經(jīng)有數(shù)據(jù)了。但是,如何在應(yīng)用程序?qū)哟沃鈩h除blogs表的第一個(gè)數(shù)據(jù)項(xiàng)呢?實(shí)際上這很簡(jiǎn)單,如下所示的命令即可辦到:
DELETE FROM blogs WHERE id = 1如果我們定義一個(gè)簡(jiǎn)單的外鍵約束,那么上述的DELETE命令不僅會(huì)刪除第一篇博客,而且與之相關(guān)的所有評(píng)論也會(huì)隨之清空,并且這一過程只需一步即可搞定,呵呵,聽起來不錯(cuò)吧。
然而,就像本文前面所說過的那樣,InnoDB存儲(chǔ)引擎還允許同時(shí)執(zhí)行級(jí)聯(lián)更新和刪除這兩種操作,下面我們會(huì)為讀者詳細(xì)介紹。
三、擴(kuò)展外鍵約束的用途
現(xiàn)在是介紹在父表數(shù)據(jù)刪除時(shí)如何對(duì)子表中的有關(guān)數(shù)據(jù)進(jìn)行級(jí)聯(lián)更新和刪除的時(shí)候了,這能夠有效簡(jiǎn)化處理這些表的應(yīng)用程序的邏輯實(shí)現(xiàn)。
為了幫您更好地理解InnoDB存儲(chǔ)引擎提供的這一特性,我們將通過示例加以說明。現(xiàn)在,我們重新定義之前見過的那兩個(gè)表,并規(guī)定特定博客被更新和刪除時(shí),要對(duì)表comments執(zhí)行相應(yīng)的級(jí)聯(lián)動(dòng)作。下面給出這兩個(gè)表的定義:
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;
如上所示,定義的第一個(gè)表blog與前面的相同,我們只需注意一下第二個(gè)表就行了。本例中,表comments的字段保持不變,不同之處在于,這次它包含了如下所示的SQL語(yǔ)句:
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`blog_id`) REFERENCES `blogs` (`id`) ON DELETE CASCADE ON UPDATE CASCADE當(dāng)然,這是負(fù)責(zé)博客更新和刪除時(shí),對(duì)其有關(guān)的評(píng)論進(jìn)行級(jí)聯(lián)更新和刪除的。
我們已經(jīng)給外鍵blog_id指定了約束,現(xiàn)在上述的兩個(gè)表之間的關(guān)系的完整性就可以完全在數(shù)據(jù)庫(kù)級(jí)別來處理了,當(dāng)然,在一些應(yīng)用程序的性能方面可能會(huì)有些損失。下面我們將介紹如何輕松完成此項(xiàng)任務(wù)。
四、外鍵約束的實(shí)際例子
前面,我們已經(jīng)定義了兩個(gè)IndoDB表,并將其作為博客應(yīng)用程序的構(gòu)造塊。現(xiàn)在,我們要做的是,每當(dāng)有博客更新和刪除時(shí),同時(shí)更新和刪除博客對(duì)應(yīng)的所有評(píng)論。
我們將通過具體的代碼加以演示。 因此,假設(shè)存儲(chǔ)在blogs表中的唯一的博客數(shù)據(jù)需要更新,那么有關(guān)評(píng)論也得同時(shí)更新,這時(shí)我們可以通過一個(gè)UPDATE語(yǔ)句來完成這一任務(wù),代碼如下所示:
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
您可能猜到了,對(duì)第一個(gè)博客數(shù)據(jù)項(xiàng)的更新將自動(dòng)地引起與該博客有關(guān)的評(píng)論的更新。現(xiàn)在,讓我們利用如下所示的SQL查詢來刪除博客:
DELETE FROM blogs WHERE id = 2這時(shí),MySQL會(huì)替我們刪除有關(guān)的評(píng)論。現(xiàn)在,我們已經(jīng)看到了外鍵約束在維護(hù)多個(gè)表的關(guān)系的一致性方面給我們帶來的幫助。是不是很方便呀?還等什么,您也動(dòng)手試一試吧!
五、小結(jié)
在本文中,我們?yōu)橄蜃x者詳細(xì)介紹了如何在更新和刪除父表數(shù)據(jù)的同時(shí),觸發(fā)有關(guān)子表數(shù)據(jù)的級(jí)聯(lián)更新和刪除操作。如您所見,當(dāng)使用InnoDB表的時(shí)候,借助于外鍵約束就可以輕松搞定這一過程。
需要說明的是,到目前為止,對(duì)示例數(shù)據(jù)庫(kù)表的操作,他們都是手工通過SQL命令進(jìn)行的,然而,在基于web的環(huán)境中,則需要利用某種服務(wù)器端語(yǔ)言來跟MySQL打交道。其中,PHP就是一個(gè)不錯(cuò)的選擇,所以,我們將在下一篇文章中討論如何通過PHP 5使用外鍵約束。
【IT168 文檔】在本文中,我們將向讀者詳細(xì)介紹如何在更新和刪除父表數(shù)據(jù)的同時(shí),觸發(fā)有關(guān)子表數(shù)據(jù)的級(jí)聯(lián)更新和刪除操作。您將看到當(dāng)使用InnoDB表的時(shí)候,借助于外鍵約束就可以輕松搞定這一過程。
一、利用外鍵約束更新并刪除MySQL中的數(shù)據(jù)
我們知道,開發(fā)能夠維護(hù)多個(gè)表的完整性的數(shù)據(jù)庫(kù)驅(qū)動(dòng)的應(yīng)用程序是一件非常復(fù)雜的事情——即使應(yīng)用程序所面對(duì)的是當(dāng)前最流行的開源關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng) MySQL服務(wù)器時(shí)也不例外。如果一個(gè)應(yīng)用程序必須處理多個(gè)數(shù)據(jù)庫(kù)表,而這些表之間有存在著某些預(yù)定義的關(guān)系,這時(shí)一旦父表中的數(shù)據(jù)被更新或者刪除,那么 這些變化必須正確反映到子表中,否則就會(huì)引發(fā)許多問題。
具體就MySQL來說,在大多數(shù)情況下類似這樣的數(shù)據(jù)庫(kù)完整性問題都可以通過使 用程序庫(kù)ORM加以解決,不過這并非解決問題的唯一出路。另一種解決方案是使用MySQL的InnoDB存儲(chǔ)引擎的外鍵約束。 在使用這個(gè)引擎的時(shí)候,我們可以在父表執(zhí)行諸如更新和刪除等操作時(shí),讓子表執(zhí)行指定的動(dòng)作來進(jìn)行響應(yīng)。
在前一篇文章中,我們演示了從父表中刪除一篇博客的數(shù)據(jù)時(shí),如何觸發(fā)對(duì)存放該博客有關(guān)評(píng)論的表中相應(yīng)數(shù)據(jù)的級(jí)聯(lián)刪除操作。
下面我們還是以前面的示例來詮釋如何在數(shù)據(jù)庫(kù)層來維護(hù)有關(guān)的表的完整性,而不是將這項(xiàng)任務(wù)讓推給處理數(shù)據(jù)層的應(yīng)用程序。
前面我們?cè)诮榻B在MySQL的InnoDB表中應(yīng)用外鍵約束的時(shí)候,都是單獨(dú)觸發(fā)級(jí)聯(lián)更新或級(jí)聯(lián)刪除操作,實(shí)際上,當(dāng)父表的鍵發(fā)生同時(shí)更新和刪除時(shí),我們還可以同時(shí)觸發(fā)對(duì)有關(guān)子表的相應(yīng)操作,這樣更易于維護(hù)數(shù)據(jù)庫(kù)的一致性。
下面我們將對(duì)此展開詳細(xì)的介紹。
二、以級(jí)聯(lián)方式刪除數(shù)據(jù)
為了保持連續(xù)性,我們?cè)诮榻B如何以級(jí)聯(lián)方式對(duì)子表數(shù)據(jù)進(jìn)行更新和刪除操作的時(shí)候,仍將使用前面所用的示例。在學(xué)習(xí)新內(nèi)容之前,讓我們先來回顧一下當(dāng)特定的博客文章給刪掉時(shí),如何使用外鍵約束刪除存儲(chǔ)評(píng)論的數(shù)據(jù)表中的有關(guān)數(shù)據(jù),注意,這里只涉及到刪除操作。
下面是我們示例中用到的兩個(gè)表的定義:
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;
上面的代碼中,我們定義了兩個(gè)簡(jiǎn)單的InnoDB表,第一個(gè)用于存儲(chǔ)博客數(shù)據(jù),第二個(gè)用來保存博客的有關(guān)評(píng)論。很明顯,這兩個(gè)表之間存在著一對(duì)多的關(guān)系,這正好可以用來演示外鍵約束的好處。現(xiàn)在,給我們的表填充如下所示的數(shù)據(jù):
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')
好了,現(xiàn)在表中已經(jīng)有數(shù)據(jù)了。但是,如何在應(yīng)用程序?qū)哟沃鈩h除blogs表的第一個(gè)數(shù)據(jù)項(xiàng)呢?實(shí)際上這很簡(jiǎn)單,如下所示的命令即可辦到:
DELETE FROM blogs WHERE id = 1如果我們定義一個(gè)簡(jiǎn)單的外鍵約束,那么上述的DELETE命令不僅會(huì)刪除第一篇博客,而且與之相關(guān)的所有評(píng)論也會(huì)隨之清空,并且這一過程只需一步即可搞定,呵呵,聽起來不錯(cuò)吧。
然而,就像本文前面所說過的那樣,InnoDB存儲(chǔ)引擎還允許同時(shí)執(zhí)行級(jí)聯(lián)更新和刪除這兩種操作,下面我們會(huì)為讀者詳細(xì)介紹。
三、擴(kuò)展外鍵約束的用途
現(xiàn)在是介紹在父表數(shù)據(jù)刪除時(shí)如何對(duì)子表中的有關(guān)數(shù)據(jù)進(jìn)行級(jí)聯(lián)更新和刪除的時(shí)候了,這能夠有效簡(jiǎn)化處理這些表的應(yīng)用程序的邏輯實(shí)現(xiàn)。
為了幫您更好地理解InnoDB存儲(chǔ)引擎提供的這一特性,我們將通過示例加以說明。現(xiàn)在,我們重新定義之前見過的那兩個(gè)表,并規(guī)定特定博客被更新和刪除時(shí),要對(duì)表comments執(zhí)行相應(yīng)的級(jí)聯(lián)動(dòng)作。下面給出這兩個(gè)表的定義:
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;
如上所示,定義的第一個(gè)表blog與前面的相同,我們只需注意一下第二個(gè)表就行了。本例中,表comments的字段保持不變,不同之處在于,這次它包含了如下所示的SQL語(yǔ)句:
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`blog_id`) REFERENCES `blogs` (`id`) ON DELETE CASCADE ON UPDATE CASCADE當(dāng)然,這是負(fù)責(zé)博客更新和刪除時(shí),對(duì)其有關(guān)的評(píng)論進(jìn)行級(jí)聯(lián)更新和刪除的。
我們已經(jīng)給外鍵blog_id指定了約束,現(xiàn)在上述的兩個(gè)表之間的關(guān)系的完整性就可以完全在數(shù)據(jù)庫(kù)級(jí)別來處理了,當(dāng)然,在一些應(yīng)用程序的性能方面可能會(huì)有些損失。下面我們將介紹如何輕松完成此項(xiàng)任務(wù)。
四、外鍵約束的實(shí)際例子
前面,我們已經(jīng)定義了兩個(gè)IndoDB表,并將其作為博客應(yīng)用程序的構(gòu)造塊。現(xiàn)在,我們要做的是,每當(dāng)有博客更新和刪除時(shí),同時(shí)更新和刪除博客對(duì)應(yīng)的所有評(píng)論。
我們將通過具體的代碼加以演示。 因此,假設(shè)存儲(chǔ)在blogs表中的唯一的博客數(shù)據(jù)需要更新,那么有關(guān)評(píng)論也得同時(shí)更新,這時(shí)我們可以通過一個(gè)UPDATE語(yǔ)句來完成這一任務(wù),代碼如下所示:
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
您可能猜到了,對(duì)第一個(gè)博客數(shù)據(jù)項(xiàng)的更新將自動(dòng)地引起與該博客有關(guān)的評(píng)論的更新。現(xiàn)在,讓我們利用如下所示的SQL查詢來刪除博客:
DELETE FROM blogs WHERE id = 2這時(shí),MySQL會(huì)替我們刪除有關(guān)的評(píng)論。現(xiàn)在,我們已經(jīng)看到了外鍵約束在維護(hù)多個(gè)表的關(guān)系的一致性方面給我們帶來的幫助。是不是很方便呀?還等什么,您也動(dòng)手試一試吧!
五、小結(jié)
在本文中,我們?yōu)橄蜃x者詳細(xì)介紹了如何在更新和刪除父表數(shù)據(jù)的同時(shí),觸發(fā)有關(guān)子表數(shù)據(jù)的級(jí)聯(lián)更新和刪除操作。如您所見,當(dāng)使用InnoDB表的時(shí)候,借助于外鍵約束就可以輕松搞定這一過程。
需要說明的是,到目前為止,對(duì)示例數(shù)據(jù)庫(kù)表的操作,他們都是手工通過SQL命令進(jìn)行的,然而,在基于web的環(huán)境中,則需要利用某種服務(wù)器端語(yǔ)言來跟MySQL打交道。其中,PHP就是一個(gè)不錯(cuò)的選擇,所以,我們將在下一篇文章中討論如何通過PHP 5使用外鍵約束。
關(guān)鍵字:MySQL、數(shù)據(jù)庫(kù)、服務(wù)器端
新文章:
- CentOS7下圖形配置網(wǎng)絡(luò)的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統(tǒng)后丟失windows啟動(dòng)項(xiàng)
- CentOS單網(wǎng)卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗(yàn)證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網(wǎng)打印機(jī)IP講解
- CentOS7使用hostapd實(shí)現(xiàn)無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網(wǎng)絡(luò)重啟出錯(cuò)
- 解決Centos7雙系統(tǒng)后丟失windows啟動(dòng)項(xiàng)
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統(tǒng)有什么不同呢
- Centos 6.6默認(rèn)iptable規(guī)則詳解