我有一个有三个表和外键'On Delete‘约束的模式,如下所示:
| -> FK (cascade) -> |
Organisation | | Users
| - FK (cascade) Categories -> FK(restrict) -> |如果我删除一个组织,我想删除用户和与它相关的类别,但如果用户引用它,我不能允许删除一个类别,除非整个组织被删除。
目前,如果我删除一个组织,类别删除失败,如果有用户引用它。这似乎表明MySQl正在处理用户表之前的类别表上的外键约束。
如果在类别之前清除了user表中的用户,这将不会是一个问题。
有没有办法告诉MySQl处理这些FK约束的顺序是什么,以便按照指定的顺序清除表?
注意:我可以添加一些代码来显式清除用户表,但是这在代码的设计中是很复杂的,所以我还不想去那里。
还要注意的是,所需的安全性限制了我对模式所能做的事情,因此更改FK约束或禁用对它们的检查并不是一个真正的选择。我可以换个安检单换一次。除非没有其他办法,否则我不想永久放松安全措施。最好像上面那样编写额外的代码。
下面是表的Create语句,编辑这些语句以删除不相关的字段。
CREATE TABLE `organisation` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`orgGUID` varchar(36) NOT NULL,
`archivedFlag` tinyint(3) unsigned NOT NULL DEFAULT '0',
`orgName` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
UNIQUE KEY `org_guid_UNIQUE` (`orgGUID`)
) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userGUID` varchar(36) NOT NULL,
`name` varchar(45) NOT NULL,
`orgGUID` varchar(36) NOT NULL,
`userType` smallint(6) DEFAULT NULL,
`PwHash` varchar(255) DEFAULT NULL,
`ethnicityGUID` varchar(36) DEFAULT NULL ,
`genderGUID` varchar(36) DEFAULT NULL ,
`yearGroupGUID` varchar(36) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
UNIQUE KEY `userGUID_UNIQUE` (`userGUID`),
KEY `fk_user_org_idx` (`orgGUID`),
KEY `fk_ethnicity_category_idx` (`ethnicityGUID`),
KEY `fk_gender_category_idx` (`genderGUID`),
CONSTRAINT `fk_ethnicity_category` FOREIGN KEY (`ethnicityGUID`) REFERENCES `categories` (`id`) ON UPDATE NO ACTION,
CONSTRAINT `fk_gender_category` FOREIGN KEY (`genderGUID`) REFERENCES `categories` (`id`) ON UPDATE NO ACTION,
CONSTRAINT `fk_user_org` FOREIGN KEY (`orgGUID`) REFERENCES `organisation` (`orgGUID`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=162 DEFAULT CHARSET=utf8;
CREATE TABLE `categories` (
`id` varchar(36) NOT NULL,
`orgGUID` varchar(36) NOT NULL,
`categoryType` varchar(20) NOT NULL,
`category` varchar(45) NOT NULL,
`priority` int(11) NOT NULL,
`analysisCode` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
KEY `fk_category_org_idx` (`orgGUID`),
CONSTRAINT `fk_category_org` FOREIGN KEY (`orgGUID`) REFERENCES `organisation` (`orgGUID`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;发布于 2018-10-19 09:58:15
根据官方说法,您无法控制级联操作的顺序。然而,你可能会滥用一些无证件的行为:
fk_category_org-constraint应该有效fk_category_org重命名为例如,fk_z_category_org应该可以工作这是没有记录的,可以随时改变(并且可能受到其他因素的影响)。
尽管如此,正确的方法(以及其他对on cascade来说太复杂的事情)将是在organisation-table上添加一个before delete-触发器,“手动”先删除用户,然后删除类别。before delete-triggers是在on cascade之前执行的(因此您可以决定是否保留这些文件,尽管这可能会产生误导)。
还不完全清楚这是否是您的有意行为,但目前,用户可以有一个属于组织1的类别,而他被分配到组织2。删除组织1仍然会失败。看起来,这似乎是您希望通过您的设计来防止的,但是如果您希望删除在这种情况下也能工作,您需要使用触发器才能将其合并(或在您的应用程序中手动删除它),除非您还在类别表中级联,否则级联将无法工作。
https://stackoverflow.com/questions/52885132
复制相似问题