我的应用程序将大量数据从数据库加载到复杂的数据结构中。内存数据结构重新组合数据库的结构,这意味着如果数据库包含以下表:
然后我有A,B和C类,以及:
这意味着如果我加载数据库,我必须以正确的顺序加载它。如果我首先加载C,那么它会抱怨它不能设置值C :: m_b,因为它应指向的实例未加载。
问题是当A中的列也是其他表之一的外键时,让我们说C。
我可以通过将所有外键加载为字符串来解决问题,然后在加载所有数据后执行查找,但由于我有时需要加载数百万条记录,因此我无法承担这些内存(虽然是临时的)字符串。
阅读好的设计(例如“大型C ++软件设计”一书)后,在我看来,根本没有循环引用是个坏主意。 例如。如果文件X.H包含Y.H,但是Y.H也包括X.H你可能有一个糟糕的设计;如果X类依赖于Y类,反之亦然,那么你可能有一个糟糕的设计,应该通过提取这个依赖并引入第三个Z来解决,它取决于X和Y(X和Y将不再依赖于彼此)
将此设计规则扩展到数据库设计是否是一个好主意?换句话说:阻止外键中的循环引用。
答案 0 :(得分:5)
从数据建模的角度来看,循环依赖并没有从根本上“错误”。这并不意味着模型是错误的。
不幸的是,大多数SQL DBMS无法有效实现此类约束,因为它们不支持多个表更新。通常,唯一的方法是临时暂停一个或多个约束(例如使用“可延迟”外键或类似功能)或通过更改模型以使约束的某些部分可选(将其中一个引用列放入新表)。这只是一个令人讨厌的SQL限制的解决方法,但是,这并不意味着你做错了什么。
答案 1 :(得分:4)
您必须为您拥有的数据建模。如果数据中存在循环关系(例如,每张照片属于一个文件夹;但每个文件夹都有一张封面照片),那么将其建模为数据库中的循环关系是正确的。
我在使用Oracle时只遇到过这种情况,所以我没有机会查看如何在其他数据库上实现这种关系。但是对于Oracle,你可以在这里阅读我的文章:
http://www.databasesandlife.com/circular-dependencies-on-foreign-key-constraints-oracle/
答案 2 :(得分:2)
您需要循环引用的唯一时间是在创建层次结构时,例如组织树。
Table Employees
EmployeeID <----------|
SupervisorEmployeeID ---|
答案 3 :(得分:1)
是的,数据库中的周期性依赖性是重新思考设计的一个很好的借口。