[英]MariaDB/MySQL foreign key constraint: possible to request cascade at time of delete?
I have used PHP code to preserve database integrity for years, but now I am switching from MyISAM to InnoDB and thought it might be nice to utilize foreign key constraints, letting the DB carry more of the load. 多年来,我一直在使用PHP代码来维护数据库的完整性,但是现在我从MyISAM切换到InnoDB,并认为利用外键约束可能会很好,从而让数据库承担更多的负载。 But I want to confirm with the user before doing a cascade, so the constraints would be declared as ON DELETE RESTRICT
. 但是我想在进行级联之前与用户确认,因此将约束声明为ON DELETE RESTRICT
。 When I get the error, I would let the user know that there are dependent records and how many, and if they say, "Sure, delete them," it would be nice to let the database do a cascading delete. 收到错误消息后,我将通知用户有相关记录以及有多少相关记录,如果它们说“确定,请删除它们”,最好让数据库进行级联删除。 Is it possible to tell a specific DELETE
statement to go ahead and cascade? 是否可以告诉特定的DELETE
语句继续进行级联? I expected an option or something on the DELETE
command (eg pseudocode DELETE FROM table WHERE ... CASCADE TO child-table
), but I didn't see anything. 我期望在DELETE
命令上有一个选项或其他内容(例如,伪代码DELETE FROM table WHERE ... CASCADE TO child-table
),但是我什么也没看到。
Example (very standard many-to-many): 示例(非常标准的多对多):
CREATE TABLE `person` (
`PersonID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`FullName` varchar(100) CHARACTER SET utf8mb4 NOT NULL DEFAULT '',
<many other fields>,
PRIMARY KEY (`PersonID`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `category` (
`CategoryID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`Category` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
PRIMARY KEY (`CategoryID`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `percat` (
`PersonID` mediumint(8) unsigned NOT NULL DEFAULT 0,
`CategoryID` mediumint(8) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`PersonID`,`CategoryID`),
FOREIGN KEY (`PersonID`) REFERENCES `person`(`PersonID`) ON DELETE RESTRICT,
FOREIGN KEY (`CategoryID`) REFERENCES `category`(`CategoryID`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=ascii COLLATE=ascii_bin;
I found How to cascade-delete temporarily or on-demand? 我发现了如何临时或按需级联删除? but: (a) it's for SQLServer, not MySQL (well, technically I'm using MariaDB 10.2.4, if that makes a difference), so I don't know if I have additional options available to me, and (b) such stored procedure code wouldn't be any simpler than the PHP code I already have (and less visible when I'm developing), so I don't see the point in swapping one for the other. 但是:(a)适用于SQLServer,而不适用于MySQL(从技术上讲,我使用的是MariaDB 10.2.4,如果有所不同),所以我不知道我是否还有其他可用的选项,以及(b)这样的存储过程代码不会比我已经拥有的PHP代码简单(并且在我开发时就不那么明显了),因此我看不出将其中一个替换为另一个的意义。
Short answer: No. 简短答案:不可以。
Longer answer: 更长的答案:
The answer is simple-minded: FKs are simple-minded. 答案很简单:FK很简单。 When you ask for more than trivial actions, you are asking for too much of FKs, and you need to build the "business logic" into your application. 当您要执行的操作不仅仅涉及琐碎的操作时,您会要求太多的FK,并且需要在应用程序中构建“业务逻辑”。
Ditto for Triggers. 同上触发器。
MySQL (and MariaDB) have always been "lean and mean" compared to the heavy hitters. 与沉重的打击者相比,MySQL(和MariaDB)始终“精简而卑鄙”。 FKs exist as a check on a feature list "yes, we have FKs, too". FK存在于功能列表中,“是的,我们也有FK”。 So, anything esoteric in the details of FKs are quite likely missing. 因此,在FK细节中任何深奥的东西很可能会丢失。
Sometimes the syntax is implemented without any real code behind it -- CHECK
; 有时,语法的实现没有背后的任何实际代码CHECK
; INDEX(x DESC)
. INDEX(x DESC)
。 (The latter is finally being implemented in 8.0, but I would estimate the number of use cases to be somewhere around one in a thousand.) (后者最终在8.0中实现,但我估计用例的数量大约为千分之一。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.