MySQL的外键约束级联删除(一)

2014-11-24 13:57:20 · 作者: · 浏览: 0
MySQL的外键约束级联删除
在更新 数据库时使用外键约束
  第一个表存储一些简单博客数据,而第二个表则存放这些博客的有关评论。这例子的巧妙之处在于,它给子表定义了一个外键约束,从而允许我们在博客文章被删除时自动地删除有关的所有评论。下面给出这两个表的定义,它们建立了一个一对多的关系:
01
DROP   TABLE   IF   EXISTS  `test`.`blogs`;
02

03
CREATE   TABLE  `test`.`blogs` (
04

05
`id`  INT ( 10 ) UNSIGNED AUTO_INCREMENT,
06

07
`title`  TEXT ,
08

09
`content`  TEXT ,
10

11
`author`  VARCHAR ( 45 )  DEFAULT   NULL ,
12

13
PRIMARY   KEY  (`id`)
14

15
) ENGINE = InnoDB  DEFAULT  CHARSET = utf8;
16

17
   
18

19
DROP   TABLE   IF   EXISTS  `test`.`comments`;
20

21
CREATE   TABLE  `test`.`comments` (
22

23
`id`  INT ( 10 ) UNSIGNED AUTO_INCREMENT,
24

25
`blog_id`  INT ( 10 ) UNSIGNED  DEFAULT   NULL ,
26

27
`comment`  TEXT ,
28

29
`author`  VARCHAR ( 45 )  DEFAULT   NULL ,
30

31
PRIMARY   KEY  (`id`),
32

33
KEY  `blog_ind` (`blog_id`),
34

35
CONSTRAINT  `comments_ibfk_1`  FOREIGN   KEY  (`blog_id`)  REFERENCES  `blogs` (`id`)  ON   UPDATE   CASCADE
36

37
) ENGINE = InnoDB  DEFAULT  CHARSET = utf8;

  除了给以上两个InnoDB表定义一些简单字段外,上述的代码还使用了一个外键约束,使得每当父表的“id”键更新时,表comments的相应内容也会级联更新。给父字段“id”定义约束的代码如下所示:
1
CONSTRAINT  `comments_ibfk_1`  FOREIGN   KEY  (`blog_id`)  REFERENCES  `blogs` (`id`)  ON   UPDATE   CASCADE

  InnoDB引擎除了可以规定根据父表完成的操作对子表进行的级联更新以外,还可以执行其他的操作,包括“NO ACTION”和“RESTRICT”,这样即使父表发生更新或者删除操作,也不会引起对子表的任何操作。
  现在,根据上面的MySQL表的定义,填充如下所示的数据:
1
INSERT   INTO  blogs (id, title, content, author)  VALUES  ( NULL , ' Title of the first blog entry ' ,  ' Content of the first blog entry ' ,  ' Tom ' )
2

3
INSERT   INTO  comments (id, blog_id, comment, author)  VALUES  ( NULL ,  1 ,  ' Commenting first blog entry ' ,  ' Susan Norton ' ), ( NULL ,  1 ,  ' Commenting first blog entry ' ,  ' Rose ' )

  然后,由于某种原因,我们更新了第一个博客数据,那么只要运行下列SQL语句,与该博客文章有关的所有评论也会随之自动更新:
1
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

  这看起来非常不错,对吧 前面讲过,外键约束容许您将表之间的关系的维护工作委托给数据库层,这意味着编写与数据层交互的应用程序时可以省去不少的代码。
  此外,我们也可以触发级联删除操作,这与前面演示的情形非常类似。因此,下面我们继续使用早先定义的两个示例表来演示当某篇博客文章的数据被删除时,如何利用外键约束删除相应的评论。
不使用外键约束时的数据删除
  为了说明当父表数据被删除时,外键约束在维护数据库完整性方面发挥的作用,我们将重建前面的例子,这次使用MyISAM表。首先,我们需要定义数据表,具体代码如下所示:
01
DROP   TABLE   IF   EXISTS  `test`.`blogs`;
02

03
CREATE   TABLE  `test`.`blogs` (
04

05
`id`  INT ( 10 ) UNSIGNED AUTO_INCREMENT,
06

07
`title`  TEXT ,
08

09
`content`  TEXT ,
10

11
`author`  VARCHAR ( 45 )  DEFAULT   NULL ,
12

13
PRIMARY   KEY  (`id`)
14

15
) ENGINE = MyISAM  DEFAULT  CHARSET = utf8;
16

17
   
18

19
DROP   TABLE   IF   EXISTS  `test`.`comments`;
20

21
CREATE   TABLE  `test`.`comments` (
22

23
`id`  INT ( 10 ) UNSIGNED AUTO_INCREMENT,
24

25
`blog_id`  INT ( 10 ) UNSIGNED  DEFAULT   NULL ,
26

27
`comment`  TEXT ,
28

29
`author`  VARCHAR ( 45 )  DEFAULT   NULL ,
30

31
PRIMARY   KEY  (`id`)
32

33
) ENGINE = MyISAM  DEFAULT  CHARSET = utf8;

  好了,我们已经建好了两个示例表,需要注意的是,它们使用的是默认的MyISAM数据库引擎,所以不支持外键约束。
  定义的这两个表构成了博客应用程序的数据层,接下来我们在其中填上一些数据,所用的代码如下所示:
1
INSERT   INTO  blogs (id, title, content, author)  VALUES  ( NULL , ' Title of the first blog entry ' ,  ' Content of the first blog entry ' ,  ' Tom ' )
2

3
INSERT   INTO  comments (id, blog_id, comment, author)  VALUES  ( NULL ,  1 ,  ' Commenting first blog entry ' ,  '