6

我正在存储目录和文件的文件系统层次结构。

在 innodb 表中,我存储每个目录/文件的详细信息,并使用将在删除时级联的外键约束维护父子关系。

myisam 表用于通过全文搜索来搜索这些目录/文件。它包含每行的名称和 ID。

数据表(innodb 表)中的任何行都会在搜索表(myisam 表)中具有相应的行,并且从数据表中添加或删除行必须反映在搜索表中。

我试图找到在删除父目录时保持两个表之间数据一致性的最佳解决方案。innodb 表很好。我删除父级,删除级联通过子级,直到它们全部被删除。从 myisam 表中删除相应的行比较困难。

我的第一个想法是在 innodb 表上使用 on-delete 触发器。当一行被删除时,它会从 myisam 表中删除相应的行。然而,由于 MySQL 在级联删除期间不激活触发器(一个已知的 7 年错误,通过在手册中提到缺乏支持而得到修复),这不是一个选项。

我的第二个想法是在搜索表中放了一个父子关系,但它是一个myisam表,支持全文搜索功能,所以不支持外键约束。

我听说 innodb 现在支持全文搜索,所以我想也许我可以更改搜索表引擎,但它仅在实验室版本中可用。

我最后的想法是放弃外键约束,只使用触发器来保持数据一致性。删除时,从 innodb 和 myisam 表中删除 parent = OLD.id。但是,为了防止可能破坏表中所有数据的无限循环,MySQL 不支持操作激活触发器的同一个表中的数据。

我已经诉诸于通过请求循环以编程方式检索父目录下的所有子目录,但是,我觉得必须有更好的选择。有没有其他更有效的解决方法?在这一点上,我能想到的仅有的两个选项是等待上述方法之一被修复或更改为不同的 RDBMS,例如支持从级联删除触发触发器的 PostgreSQL。

任何其他想法将不胜感激。

4

1 回答 1

1

这些令人头疼的问题正是让我尽可能远离 mysql 的原因。

...我觉得必须有更好的选择...

遗憾的是没有。简单的问题是你不能删除级联并且让mysql知道它刚刚删除了什么。因此,您唯一的选择是在删除之前找出将要删除的内容(这是您最后建议的算法)。

由于级联会破坏您的数据,因此您不应使用on update cascade密钥,以免尝试删除父目录而不删除子目录将失败。

我建议您创建一个程序来为您完成繁重的工作(删除)。这将防止您的应用程序和数据库之间的大 IO,因为它回避所有目录。如果您曾经通过不同的应用程序访问同一个数据库(或者您只想手动执行某些操作),我还将为此提供通用代码。

正如我首先所说,这些天我主要使用 postgresql。这是为什么的一个例子。

于 2012-05-19T15:05:39.253 回答