(转)数据库更新或者删除数据是通过外键约束同步更新

问题:在写毕业设计时,只是建立了五张表,但是可能每次都需要更新或者删除几张表的数据,之后陷入思考

在网上也搜了好多,之后得到了一些结论:

这里先把从别处找来的资料放到这里,然后再总结下需要注意的地方

InnoDB中对外键约束定义的语法看起来如下:

[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)

    REFERENCES tbl_name (index_col_name, ...)

    [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}]

    [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]

 

外键定义服从下列情况:

         ·  所有tables必须是InnoDB型,它们不能是临时表。

         ·  在引用表中,必须有一个索引,外键列以同样的顺序被列在其中作为第一列。这样一个索引如果不存在,它必须在引用表里被自动创建。

         ·  在引用表中,必须有一个索引,被引用的列以同样的顺序被列在其中作为第一列。

         ·  不支持对外键列的索引前缀。这样的后果之一是BLOB和TEXT列不被包括在一个外键中,这是因为对这些列的索引必须总是包含一个前缀长度。

         ·  如果CONSTRAINT symbol被给出,它在数据库里必须是唯一的。如果它没有被给出,InnoDB自动创建这个名字。

其中tbl_name被称作为父表,定义外键的表被称作为子表。

外键约束对子表的含义: 

  如果在父表中找不到候选键,则不允许在子表上进行insert/update(即默认情况下(RESTRICT下),定义了外键以后就不能对子表进行删除和修改操作) 

但是实际开发中,我们想要做的是更新父表的数据,同时更新子表相关数据,删除父表数据后,可能需要对子表进行set null置空操作,那么先来看看外键约束对父表的含义吧:

  在父表上进行update/delete以更新或删除在子表中有一条或多条对应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的on update/on delete子句, InnoDB支持5种方式, 分列如下 

  
  . cascade方式 
   在父表上update/delete记录时,同步update/delete掉子表的匹配记录 
   On delete cascade从mysql3.23.50开始可用; on update cascade从mysql4.0.8开始可用 

  . set null方式 
   在父表上update/delete记录时,将子表上匹配记录的列设为null 
   要注意子表的外键列不能为not null 
   On delete set null从mysql3.23.50开始可用; on update set null从mysql4.0.8开始可用 

  . No action方式 
   如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作 
   这个是ANSI SQL-92标准,从mysql4.0.8开始支持 

  . Restrict方式 
   同no action, 都是立即检查外键约束 

  . Set default方式 
   解析器认识这个action,但Innodb不能识别,不知道是什么意思... 
  
  注意:trigger不会受外键cascade行为的影响,即不会解发trigger 

在mysql中,与SQL标准相违背的三点 
1.       如果在父表中有多个key值相同,那么在进行外键check时,会当成有相同key值的其他行不存在; 比如当定义了一个restrict行为外键时,一个子表行对应到多个父表行(具有相同key值), Innodb不允许删除父表上的所有这些行 

2.       父子表是同一个表,自我参照时不允许指定on update cascade, on update set null 
从mysql4.0.13开始,允许同一个表上的on delete set null 
从mysql4.0.21开始,允许同一个表上的on delete cascade 
但级联层次不能超出15 

3, Innodb在检查unique,constraint约束时,是row by row而不是语句或事务结束; 

  SQL标准中对constraint的检查是在语句执行完成时 

理论讲完以后,我来举个简单的例子:

父表的创建语句如下:

 

 CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(244) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`),
  CONSTRAINT `test_ibfk_1` FOREIGN KEY (`name`) REFERENCES `use2` (`name`) ON D
ELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

 

子表创建语句如下:

//这个是子表,子表name字段必须是索引,参见上面的规则
 CREATE TABLE `user` (
  `name` varchar(244) NOT NULL,
  `gender` enum('male','female') NOT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

这里需要注意的两点:

①如果主表想使用on delete set null ,则外键字段必须在子表中设置的为null(刚开始的时候一直不知道哪里出错,搞了半天。。)

②父表设置on update cascade表示只要父表更新,子表相应字段也要更新,所以这就要求,父表和子表这两个字段的数据类型和长度必须保持一致,否则会出错的

③默认情况下是严格方式,说通俗点就是子表中一旦有对应的数据和父表相对应,则父表相应的数据就不能做删除和更新操作了

其实这些理解到了以后,外键的约束这个知识点基本上没什么问题了

转载至:

https://blog.csdn.net/u010242979/article/details/25750649

 

mysql在Navicat中的表现则是:

直接添加外键约束是选择cascade

如图:

 

改变之后的代码如下:

CREATE TABLE `t_buyercart` (
  `buyerCartId` varchar(11) NOT NULL,
  `buyerCartByName` varchar(20) DEFAULT NULL,
  `buyerCartPrice` double DEFAULT NULL,
  `buyerCartDiscount` double DEFAULT NULL,
  `buyerCartStone` int(11) DEFAULT NULL,
  `buyerCartNum` int(11) DEFAULT NULL,
  KEY `buyerCartId` (`buyerCartId`),
  KEY `buyerCartByName` (`buyerCartByName`),
  KEY `buyerCartStone` (`buyerCartStone`),
  CONSTRAINT `t_buyercart_ibfk_1` FOREIGN KEY (`buyerCartId`) REFERENCES `t_user` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `t_buyercart_ibfk_2` FOREIGN KEY (`buyerCartByName`) REFERENCES `t_mi` (`MiName`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `t_buyercart_ibfk_3` FOREIGN KEY (`buyerCartStone`) REFERENCES `t_mi` (`MiStone`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

所以

 

posted @ 2018-05-20 21:41  逐风一缕  阅读(640)  评论(0编辑  收藏  举报