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找到无效的外键的主要内容,如果未能解决你的问题,请参考以下文章
Oracle DB - ORA-00904:选择时出现“无效标识符”错误