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

    尽量指定类和方法的final修饰符 带有final修饰符的类是不可派生的 在java核心api中 有许多应用final的例子 例如 java.lang.string整个类都是final的 为类指定fi ...

  2. “通用类型系统”(CTS)

    一.什么是“通用类型系统”(CTS) 描述类型的定义和行为 二.CTS规范 一个类型可以包含零个或者多个成员1,成员①字段(Field)作为对象状态一部分的数据变量.字段根据名称和类型来区分②方法(M ...

  3. [ 转载 ] Java基础11--Java总结篇系列:Java泛型

    一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 1 public class GenericTest { 2 3 public static void main(Stri ...

  4. 面向对象设计原则 依赖倒置原则(Dependency Inversion Principle)

    依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口,不要依赖于具体实现. 简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块 ...

  5. JZYZOJ1140 飞船控制站

    http://172.20.6.3/Problem_Show.asp?id=1140 p1140 就一道非常普通的二分,但是非常蛋疼的是验证mid left的过程一直错(就是写一个k次循环然后根据可行 ...

  6. 【20181102T2】飞越行星带【智商题+最小瓶颈路】

    题面 [正解] 一眼不可做啊 --相当于求路线上穿过的点最小距离最大 最小最大--二分啊 现在相当于给一个直径,要判断这个直径是否能从左边穿到右边 我们可以在距离不超过直径的点连一条边,\(y=0\) ...

  7. Git 初学者使用指南及Git 资源整理

    Git 资源整理 Git is a free and open source distributed version control system designed to handle everyth ...

  8. java多线程技术之条件变量

    上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇 ...

  9. bzoj 3240 矩阵乘法+十进制快速幂

    首先,构造出从f[][i]->f[][i+1]的转移矩阵a,和从f[i][m]->f[i+1][1]的转移矩阵b, 那么从f[1][1]转移到f[n][m]就是init*(a^(m-1)* ...

  10. classList

    1,classList.remove(value) // 删除value项 2, classList.contains(value) // 判断列表中是否存在给定的值,存在返回true,否则返回fal ...