在本文中,咱们将向读者详细介绍如何在更新和删除父表数据的同时,触发有关子表数据的级联更新和删除操做。您将看到当使用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