如何调试mysql外键约束,在生产环境中删除级联而不是从子表中删除行

如何调试mysql外键约束,在生产环境中删除级联而不是从子表中删除行,mysql,database,debugging,foreign-key-relationship,rdbms,Mysql,Database,Debugging,Foreign Key Relationship,Rdbms,我定义了两个表以及它们之间的外键约束,如下所示: | users | CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `account_master_id` int(11) NOT NULL, `user_type_id` int(11) NOT NULL, `user_group_id` int(11) NOT NULL, `user_type_code` char(1) NOT NULL, `m

我定义了两个表以及它们之间的外键约束,如下所示:

| users | CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `account_master_id` int(11) NOT NULL,
  `user_type_id` int(11) NOT NULL,
  `user_group_id` int(11) NOT NULL,
  `user_type_code` char(1) NOT NULL,
  `membership_number` varchar(40) NOT NULL,
  `password` varchar(60) NOT NULL,
  `email` varchar(200) NOT NULL,
  `isd` varchar(10) NOT NULL,
  `mobile` varchar(20) NOT NULL,
  `passenger_id` int(11) NOT NULL,
  `added_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `added_by` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`),
  KEY `account_master_id` (`account_master_id`),
  CONSTRAINT `acMaster_to_user` FOREIGN KEY (`account_master_id`) REFERENCES `account_master` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=189 DEFAULT CHARSET=utf8 |


user_oauth | CREATE TABLE `user_oauth` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `service` varchar(30) NOT NULL,
  `auth_id` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  `auto_share` tinyint(4) NOT NULL,
  `photo` varchar(255) NOT NULL,
  `auth_token_short` varchar(255) DEFAULT NULL,
  `auth_details` text NOT NULL,
  `device_type` varchar(60) NOT NULL,
  `login_date` datetime NOT NULL,
  `login_ip` varchar(20) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user` (`user_id`),
  CONSTRAINT `user_to_oauth` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=latin1 |
从users表中删除行时,从本地和临时环境中的user_oauth表中删除相应的条目。但是,同样的事情在生产环境中不起作用。我想知道如何调试这个

更新:

  • 两个表都是innodb
  • 在严格模式下运行mysql

外键可能不起作用的原因是:

  • 它们不受支持(例如在MyISAM表上)
  • 他们是残疾人
MySQL允许您通过将系统变量设置为
0
来禁用外键约束。这将允许您违反所有外键约束(例如,删除父项或添加无父项的子项)。但它反过来也将禁用级联等相关功能,这些功能用于自动防止违反特定约束(例如,删除子项)——如果禁用该选项,当然不会再发生这种情况

这样做的目的是帮助您完成一些管理任务,例如,在引用数据尚未存在时导入数据,但通常不应在正常操作期间使用。如果该设置再次出现,您可能希望检查您的应用程序是否意外设置了该选项,因为默认情况下,每个服务器启动后都会启用该选项,并且必须明确禁用该选项

您可以检查当前设置,例如使用

select @@foreign_key_checks;
你可以用

SET foreign_key_checks = 1;
要再次启用它,但请注意它不会检查您的当前数据:

将外键检查设置为1不会触发对现有表数据的扫描。因此,当外部\u key\u checks=0时添加到表中的行将不会验证一致性


所以你必须自己检查并修复它。您可以在再次启用设置之前或之后执行此操作,尽管在启用设置之前执行此操作可能更容易。要触发重新检查,您可以而且应该删除并重新创建外键,以确保现在所有内容都一致。

Do
select@@foreign\u key\u checks(当该行为发生时)。如果显示为0,请修复数据,将其设置为1,然后解雇某人(除非是你自己,然后将其隐藏起来)。如果上面写着1,你将不得不寻找其他想法。谢谢,伙计,这就是区别。你能告诉我你是怎么知道的吗。我不只是想得到答案,而是想了解这个问题以及如何调试这些东西。我将添加一些关于这个选项的背景知识作为答案。怎么弄清楚很难说。如果你知道这个选项是存在的,那就没有魔力了。如果你没有,那就有点像。你也许能够推断出这样的东西一定存在,并且能够在手册中找到它。不幸的是,对于一些信息,在MySQL手册中找到正确的答案也需要魔法。(但并非所有方面都做得很好,包括技术细节)。我想一个现实的解决方案是用谷歌搜索它,或者询问了解它的人(例如stackoverflow)。谢谢你的解释。我认为这是因为从phpMyadmin导出时选择了“禁用外键检查”,并通过终端手动复制粘贴代码,最后忘记启用“外键检查”。这真的很有帮助。