MySQL找到无效的外键

Posted

技术标签:

【中文标题】MySQL找到无效的外键【英文标题】:MySQL find invalid foreign keys 【发布时间】:2012-08-08 01:46:08 【问题描述】:

我们有一个包含几百个表的数据库。使用 foreign_keys 的表使用 INNODB。

有时我们在开发、阶段和生产数据库之间传输数据(使用mysqldump 的各个表)。 mysqldump 禁用所有外键检查以方便导入数据。

因此,随着时间的推移,我们的一些非生产数据库最终会出现一些孤立记录。

我正要编写一个脚本来查找和检测整个 MySQL 数据库的任何无效(指向丢失记录的键)外键。

我知道我可以编写一个查询来逐个检查每个表和 fkey,但我想可能已经有一个工具可以做到这一点。

我会在编写这样的脚本之前检查一下是否已经有一个。

用谷歌搜索了一下......令人惊讶的是我什么也没找到。

【问题讨论】:

“无效”是什么意思?孤立的记录?具有指向不再存在的表的 FK 的表? 您可以让您的数据库自动执行此操作(取决于您使用的数据库引擎)并将其设置为 ON DELETE CASCADE,以便维护引用完整性。 除了 stefans 的评论之外,请注意您可以取消孩子或更新它,您不必删除它。 是的,我所说的无效是指孤立的记录。我将更新我的问题以更简洁。 是的,我知道“删除/更新”级联。但是,数据库中已经存在孤立记录。 ON "DELETE/UPDATE" CASCADE 将只处理未来的更新和删除。我会更新我的问题。 【参考方案1】:

如果数据已经存在并且您没有设置 fk 约束或级联来删除父级,那么您只需要:

SELECT * FROM children WHERE my_fk_id NOT IN (select id from parents);

【讨论】:

SELECT t1.* FROM table1 t1 LEFT JOIN table2 t2 ON t1.parent_id = t2.id WHERE t2.id IS NULL @Isotope 数据已经在里面了,但是我们已经有了 fk 约束。 这对于查找表上的无效键非常有用。但是,我正在寻找一种工具来为整个数据库中的所有表找到这些。 没有工具可以做这样的事情,因为这是一项非常简单的定制工作。你想对所有的孤儿做什么?删除它们?使用您最喜欢的脚本语言,只需遍历表格即可。【参考方案2】:

这些其他答案对于小表来说很好,但我认为它们在 O(n^2) 中运行,这对于大型数据库可能并不理想。相反,我使用了左连接:

SELECT * FROM children c LEFT JOIN parents p ON p.id=c.parent_id WHERE p.id IS NULL AND c.parent_id IS NOT NULL;

请注意,您可能不需要最后一个非空条件,我这样做是因为我想排除没有父母的孩子(在我的特定场景中是一个有效案例)

【讨论】:

以上是关于MySQL找到无效的外键的主要内容,如果未能解决你的问题,请参考以下文章

Rails ActiveRecord关系无效外键错误

jdbc中的外键问题

Oracle 中的外键创建问题

Oracle DB - ORA-00904:选择时出现“无效标识符”错误

sql [查找表的外键关联]找到一个表的外键postgresql #PostgreSQL

( 10 )MySQL中的外键