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

【Python】Django数据模型、级联删除、级联更新、ER图导出等的更多相关文章

  1. [原创]MYSQL中利用外键实现级联删除和更新

    MySQL中利用外键实现级联删除.更新 MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定 ...

  2. MySQL中利用外键实现级联删除、更新

    MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定在删除.更新父表时,对子表进行的相应操作 ...

  3. hibernate 级联删除报更新失败的问题(org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update)

    首先hibernate级联删除的前提是,首先需要在映射文件中配置,配置多表之间的关联关系: 下面以部门表(Dept)和员工表(Emp)为例: 1.在Emp.hbm.xml映射文件中配置many-to- ...

  4. Python mysql-表的创建,删除和更新

    2017-09-06 20:59:56 数据库的创建 CREATE DATEBASE <数据库的名称> 表的创建 CREATE TABLE <表名> (<列名1> ...

  5. 自增特性,外键,级联更新与级联删除,表间关系,SELECT用法,GROUP BY

    自增特性 自动增长的作用: 问题:为数据表设置主键约束后,每次插入记录时,如果插入的值已经存在,会插入失败. 如何解决:为主键生成自动增长的值. 自动增长的语法: 字段名 数据类型 AUTO_INCR ...

  6. [NHibernate]一对多关系(级联删除,级联添加)

    目录 写在前面 文档与系列文章 一对多关系 一个例子 级联删除 级联保存 总结 写在前面 在前面的文章中,我们只使用了一个Customer类进行举例,而在客户.订单.产品中它们的关系,咱们并没有涉及, ...

  7. MySQL外键设置 级联删除

    . cascade方式在父表上update/delete记录时,同步update/delete掉子表的匹配记录 . set null方式在父表上update/delete记录时,将子表上匹配记录的列设 ...

  8. powerdesign、navacat、ER图、uml、类图、时序图

    关于建表和生成实体以及ER图的简便方法 a:用navacat客户端生成简单的ER图,并生成建表sql,执行生成表. b:用powerdesign连接数据库,反向生成带有注释的ER图. c:用ideal ...

  9. mysql快速导出数据库ER图和数据字典(附navicat11安装教程及资源)

    ♣ mysql使用navicat11快速导出数据库ER图 ♣ mysql使用navicat11快速导出数据库数据字典 ♣ navicat11 for mysql (这里是mysql5.7.12)专业版 ...

随机推荐

  1. Mysql表连接查询

    原文地址: https://www.cnblogs.com/qiuqiuqiu/p/6442791.html 1.内联接(典型的联接运算,使用像 = 或 <> 之类的比较运算符).包括相等 ...

  2. 【推导】【贪心】Codeforces Round #472 (rated, Div. 2, based on VK Cup 2018 Round 2) D. Riverside Curio

    题意:海平面每天高度会变化,一个人会在每天海平面的位置刻下一道痕迹(如果当前位置没有已经刻划过的痕迹),并且记录下当天比海平面高的痕迹有多少条,记为a[i].让你最小化每天比海平面低的痕迹条数之和. ...

  3. Codeforces Round #359 (Div. 1) A. Robbers' watch 暴力

    A. Robbers' watch 题目连接: http://www.codeforces.com/contest/685/problem/A Description Robbers, who att ...

  4. ROS知识(9)----安装Turtlebot2和远程控制Turtlebot2

    安装turtlebot2,场景为:turtlebot2上搭载着一台电脑主机A,该电脑作为主机Master,有自带的电源和3D传感器,roscore在该台机器上启动.pc电脑远程连接A,和A通讯,pc不 ...

  5. IDA Supported Processors

    IDA supports more than 50 families of processors. The source code of some of the processor modules i ...

  6. iptables详解与Centos7 关闭防火墙

    http://www.cnblogs.com/metoy/p/4320813.html CentOS 7.0默认使用的是firewall作为防火墙,使用iptables必须重新设置一下 1.直接关闭防 ...

  7. C# 去掉webapi返回json所带的转义字符

    反序列换报错: {"Error converting value \"{\"Result\":true,\"Code\":\"\& ...

  8. SqlServer收缩日志文件

    通过收缩的方法可以释放所占空间. 第一步:将数据库的模式调整为简单模式 右击数据库名->'属性'->'选项'->恢复模式改成'简单'->点'确定'按钮. 第二步:收缩文件 右键 ...

  9. UITableView 让 cell 被选中的颜色底色快速消失,而不是一直停留在cell上

    //单元格被选中 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath ...

  10. AutoMapper: Mapper.Initialize() 只能调用一次,Why?

    最开始的代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using S ...