MariaDB如何分解删除级联[已关闭]

5uzkadbs  于 2023-03-30  发布在  其他
关注(0)|答案(1)|浏览(106)

已关闭。此问题需要超过focused。当前不接受答案。
**想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。

6天前关闭。
社区在6天前审查了是否重新打开此问题,并将其关闭:
原始关闭原因未解决
Improve this question
我有一个MariaDB数据库版本10.3.38和一个名为mw_list的表,其中有一列被其他表引用(例如mw_fieldsmw_subscribers)。其他表也可能有引用mw_fieldsmw_subscribers的约束,因此您可以知道它的去向。如果我从mw_list删除一行(父表)将发生连锁React,这意味着约束应该强制删除子表。问题是我得到超时,因为表很大。

**问题1:**当从mw_list中删除父行时,查询是否继续,假设暂停,直到约束的子查询完成?
**问题2:**当我超时后,我去检查子表,没有任何行丢失,就像没有删除一样,为什么会这样?
**问题3:**如何打破这个过程?通过删除约束并使用join子句重新构建新的查询?

我尝试删除一两行,但超时了。我希望查询完成,或者至少删除一部分子行。

b4lqfgs4

b4lqfgs41#

数据操作语句(如级联DELETE)是事务性的。整个语句完成,或者整个语句回滚到起始状态(如超时)。这解释了您观察到没有删除任何子行的原因。
如何解决这个问题?这里有一些选择。
1.跟踪所有子表,并在从父表中删除行之前显式地从这些表中删除子行。这将花费更多的SQL,但不太可能超时。
1.另一种可能性。使用max_statement_time来增加超时时间。这将给予查询有10分钟(600秒)的运行时间。

SET STATEMENT max_statement_time=600 FOR 
  DELETE FROM mw_list WHERE whatever

1.您没有向我们展示您的表定义,因此这是一个猜测:将表的ON DELETE CASCADE语句更改为ON DELETE RESTRICT。这样,当子行仍然存在时,您将无法删除任何父行。然后执行步骤1。
1.禁用foreign key checks,并显式删除子行和父行。但要注意:编程中的缺陷会导致子表中出现孤立行。

SET @@session.foreign_key_checks=0;
DELETE FROM ....

1.完全不要使用外键。你的数据库会更快。继续读...

专业提示显式外键定义的目的是强制执行完整性规则,其中一条规则是“无孤儿行”。如果您的应用能够适应少数孤儿行和其他referential integrity problems,您可以在生产环境中操作它,而无需外键定义。对于大表,这使得INSERT,UPDATE和DELETE操作大大加快。许多生产应用不使用FK,您必须更新代码以在删除父行之前删除子行。即使使用最好的代码,在实时系统中,偶尔也会出现孤儿行,你需要一个过程来清理它们。我已经用了一周的工作来达到这个目的。它会删除孤立项,并在找到要删除的孤立项时向负责人发送电子邮件。

相关问题