【问题标题】:How to automatically delete rows in a table when the corresponding rows in a 1 to 1 table are deleted?删除1对1表中的对应行时,如何自动删除表中的行?
【发布时间】:2012-03-06 00:47:08
【问题描述】:

我有两种不同的文档。一种是按文件夹组织的。另一个是由客户组织的。这是mysql中的表结构:

Table docs
ID
title

Table folderDocs
docID -> docs(ID)
folderID -> folders(ID) ON DELETE CASCADE

Table clientDocs
docID -> docs(ID)
clientID -> clients(ID) ON DELETE CASCADE

我正在寻找一种优雅的方式来在删除文件夹或客户端时自动删除文档。上述级联规则并不能完全做到这一点。 (即folderDocs中的行会被删除,但docs中对应的行会保留。)

有没有办法在mysql中设置这个,使用级联规则或其他方法,这样当级联删除folderDocs或clientDocs中的一行时,docs中的相应行也被删除? (我希望避免必须先以编程方式删除文档,然后再删除文件夹/客户端。)

感谢(提前)您的帮助。

【问题讨论】:

  • 这可能是个愚蠢的问题,但是您是否在表中将docID 设置为外键?因为你想要的听起来就像 ON DELETE CASCADE 所做的一样,但除非你设置了外键,否则它不会起作用。
  • 为什么不使用 DELETE 触发器?
  • @Rogier - 如果删除是级联的,我认为 DELETE 触发器不起作用。如果我对此有误,请纠正我。
  • 好吧,我也不确定。但我认为您可以删除 CASCADE DELETE 并在每个表上实现触发器。那么应该没问题,应该可以正常工作。

标签: php mysql cascading-deletes


【解决方案1】:

假设每个文档必须属于一个文件夹或一个客户端,那么您可能需要设置一个计划的清理作业,以使用下面的查询删除所有没有文件夹和客户端的文档

DELETE FROM docs USING docs
LEFT JOIN clientDocs c ON (c.docid = docs.id) 
LEFT JOIN folderDocs f ON (f.docid = docs.id) 
WHERE ISNULL(c.clientid) AND ISNULL(f.folderid)

【讨论】:

  • 这行得通。但现在的问题是每次查询文档时,您还需要查询文件夹和客户端以查看它们是否仍然有效。
  • 您可以将此代码添加到 clientDocs 和 folderDocs 表上的 afterDelete 触发器,以便在每次删除文档时执行它或从 cron 作业每 5 分钟运行一次查询
【解决方案2】:

我认为你不能在直接的 sql 中做到这一点。您可能需要编写一个存储过程来执行此操作。

但这是个好主意。因为您的表格的设计方式使它看起来像是多对多的关系。如果其他文件夹中仍有对文档的引用,您可以删除该文档吗?

如果假设它们是一对多关系,那么文件夹和客户端的外键应该在 doc 中,而不是单独的表中。那么你可以使用级联删除。

编辑:您可以尝试使用触发器。 http://dev.mysql.com/doc/refman/5.0/en/triggers.html

但它仍然需要编写一些代码(以触发器的形式)

【讨论】:

  • 谢谢,docs&folderDocs,docs&clientDocs是1:1的关系。
猜你喜欢
  • 2019-03-04
  • 2016-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多