简体   繁体   English

如何检查 MySQL 中关系的完整性?

[英]How do I check the integrity of a relationship in MySQL?

I do something like this:我做这样的事情:

SET foreign_key_checks = 0;
//many different operations on several tables
SET foreign_key_checks = 1;

How can I verify that my entire base is consistent?如何验证我的整个基础是一致的? I want to be sure that all relationships are properly maintained.我想确保所有关系都得到妥善维护。 For example, if I delete a "country" with id: 20, I want to make sure that no "city" has a non-existent relationship "country_id" = 20.例如,如果我删除一个 id 为 20 的“国家”,我想确保没有一个“城市”与“country_id”=20 的关系不存在。

It's easier if you do not SET foreign_key_checks = 0 .如果你不SET foreign_key_checks = 0会更容易。 If you keep the constraint enforcement on, then you can't make inconsistencies or broken references.如果您继续执行约束,那么您就不能产生不一致或损坏的引用。 You get an error if you try.如果你尝试,你会得到一个错误。 So you should consider not turning off the FK checks if referential integrity is important.因此,如果参照完整性很重要,您应该考虑不要关闭 FK 检查。

If you do think you have inconsistencies, you must do a query like the following to verify there are no "orphans" that reference a parent that no longer exists:如果您确实认为您有不一致的地方,您必须执行如下查询,以验证不存在引用不再存在的父级的“孤儿”:

SELECT cities.city_id
FROM cities
LEFT OUTER JOIN countries
 ON cities.country_id = countries.country_id
WHERE countries.country_id IS NULL;

If the JOIN condition was based on equality of country_id, this means country_id must not be NULL.如果 JOIN 条件基于 country_id 的相等性,这意味着 country_id 不能是 NULL。 The left outer join returns NULL for all columns when there is no match.当没有匹配时,左外连接为所有列返回 NULL。 So if you search in the WHERE clause for cases where country_id IS NULL this will only return cities that have no match in the other table.因此,如果您在 WHERE 子句中搜索country_id IS NULL的情况,则只会返回在另一个表中不匹配的城市。

You must do a separate query for each relationship in your database.您必须对数据库中的每个关系进行单独的查询。 This can be quite a chore, and if the tables are very large, it can take a long time.这可能是一件苦差事,如果表非常大,可能需要很长时间。

I once had to do this many years ago in a buggy application that had no foreign key constraints (it used MyISAM tables).多年前,我曾经在一个没有外键约束的错误应用程序中这样做(它使用了 MyISAM 表)。 I ran a script to do all these orphan-checks every night, and eventually it grew to dozens of queries, and took hours to run.我每天晚上都运行一个脚本来执行所有这些孤儿检查,最终它增长到几十个查询,并且需要几个小时才能运行。

Then comes the part that is even harder: once you do find some orphaned records, what do you do about them?然后是更难的部分:一旦你找到了一些孤立的记录,你会怎么处理它们? Do you delete the orphans?你会删除孤儿吗? Do you change their foreign key column to reference a parent record that does still exist?您是否更改了他们的外键列以引用仍然存在的父记录? Do you restore the parent record?你恢复父记录吗? It could be any of these options, and you must have the orphaned records reviewed case by case, by someone with the knowledge and authority to choose how to resolve the issue.可以是这些选项中的任何一个,并且您必须让有知识和权力的人逐案审查孤立记录,以选择如何解决问题。

It's far better to keep the constraints enforced so you don't have to do that work.保持强制执行约束要好得多,这样您就不必做这项工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM