是否应该执行参照完整性?

时间:2010-08-23 05:23:55

标签: database database-design referential-integrity

不应强制实施参照完整性的原因之一是性能。因为Db必须根据关系验证所有更新,它只会使事情变慢,但执行和不执行的其他优缺点是什么?

因为无论如何都要在业务逻辑层中维护关系,所以它只会使db冗余。你有什么想法?

11 个答案:

答案 0 :(得分:24)

数据库负责数据。而已。周期。

如果未在数据库中完成参照完整性,则完整性。它只是相信人们不要做坏事,在这种情况下你甚至不用担心密码保护你的数据: - )

谁能说你不会让某人编写他们自己的JDBC连接客户端来完全搞砸数据,尽管你精心设计并且没有错误的业务层(事实上它可能不会无bug是完全的另一个问题,强制数据库应该保护自己。)

答案 1 :(得分:9)

首先,几乎不可能让它真正正常工作。为了有正确的工作机会,你需要将许多级联修改包装为事务,这样你在更改数据库的一部分时就不会有不同步的东西,但仍在更新依赖于其他部分的数据库。首先。这意味着代码应该简单并且只知道业务逻辑突然需要知道所有类型的并发问题。

其次,保持工作几乎是不可能的 - 每当有人触及业务逻辑时,他们需要再次处理这些并发问题。

第三,这使得参照完整性难以理解 - 将来,当有人想要了解您的数据库结构时,他们将不得不从业务逻辑中对其进行逆向工程。有了它在数据库中,它是独立的,所以你必须只看 来处理参照完整性,而不是各种不相关的问题。您有(例如)直接逻辑链,显示对特定字段的修改将触发的内容。至少对于相当多的数据库,可以自动提取该逻辑并将其转换为相当有用的文档(例如,显示依赖性的树图)。从BLL中提取相同类型的信息更可能是一个相当严肃的项目。

在另一个方向肯定有一些观点,并且有理由通过手工制作所有这些 - 可扩展性和性能最为明显。但是,如果你走这条路,你应该知道你放弃了什么以获得这种表现。在某些情况下,这是一个值得的权衡 - 但在其他情况下它不是,你需要信息做出合理的决定。

答案 2 :(得分:8)

业务逻辑层中可能维护关系。除非你能100%毫无疑问地保证你的BLL是无错误的,否则你就没有数据完整性。你不能保证。

此外,如果另一个应用程序将触及您的数据库,则不需要遵循(读取:重新实现,可能以一种微妙的方式)BLL中的规则。 可能会破坏数据,即使你以某种方式设法成为地球上3个程序员之一来编写无错误的代码。

同时,数据库为每个人强制执行相同的规则 - 数据库强制执行的规则在更新时不太可能被忽略,因为数据库不允许这样做。

答案 3 :(得分:5)

向eBay的技术研究员Dan Pritchett提出listen关于为什么某些数据库结构(如交易和参照完整性)不是教科书可能表明它们应该是的任务......它归结为类型数据,查询量和业务需求。平衡这些,它会引导你找到务实的解决方案,而不是教条的答案......

但是,假设保持BLL中的关系将保护您的数据。您不能保证未来的开发人员不会因为“性能”原因而暴露出绕过BLL的新API,或者对您的架构缺乏了解......

答案 4 :(得分:4)

问题所依据的表现假设作为一般规则是不正确的。通常,如果您需要强制执行RI,那么数据库是最有效的地方,而不是应用程序 - 否则应用程序必须重新查询更多数据才能在数据库外验证RI。

此外,数据库中的RI约束对查询优化器非常有用,可以使其他查询更有效。应用程序中的完整性约束无法实现这一点。

最后,在每个应用程序中维护完整性约束的成本通常比在一个地方执行一次更加昂贵和复杂。

答案 5 :(得分:3)

关于数据库应该是验证/控制约束的最终位置已经说了很多(我不能同意)

如果数据很重要,那么您的应用程序将不是最后一个访问数据库的应用程序,它不会是唯一的数据库。

但是关于引用完整性(和其他约束)还有另一个非常重要的事实:它记录了您的数据模型并使表之间的依赖关系显式化。

就性能而言,在某些情况下,在数据库中定义FK(或其他约束)可以使事情变得更快,因为DBMS可以依赖约束并进行适当的优化。

答案 6 :(得分:3)

但是Ingus上校,如果你已经在会话中找到了客户,你已经探测过数据库了!问题在于,然后您将销售订单写下来,但没有将其附加到产品上,因为您不了解产品。无论如何,你最终会得到孤立的记录,就像我目前正在工作的非常大的公司一样。我们的客户没有历史和历史,没有客户;那些从未购买过任何东西的未结余额的客户和销售给不存在的客户的商品 - 有趣的商业概念 - 并且它让一群非常沮丧的支持人员在全职工作中试图解决问题。把RI放在所有东西上并购买一个更大的盒子来解决任何感知到的性能问题会便宜得多。

答案 7 :(得分:2)

paxdiablo和dportas说的是什么。而我的两分钱。还有另外两个考虑因素。

为了验证新插入的参照完整性,您必须对数据库进行探测以验证该引用是否有效。您只是取消了导致您希望在应用程序中强制实施完整性的性能增益。让DBMS强制执行引用完整性实际上更快。

除此之外,请考虑您有多个应用程序在一个数据库中读取和写入数据的情况。如果在业务应用程序层中强制实施参照完整性,则必须确保所有应用程序都正确执行。否则,某些异常应用程序可能存储无效引用,并且当另一个应用程序使用该数据时,问题可能会浮出水面。那真是一团糟。 最好让DBMS为所有应用程序强制执行数据规则。

答案 8 :(得分:1)

这取决于数据,如果其高度事务性的数据(如业务事务)以及不经常更新的地方,那么在数据库中强制执行业务规则非常重要..但对于其他一切,性能影响可能不值得它..

答案 9 :(得分:1)

如果您要维护业务层中的关系,则可以保证在数据库中使用数据库中的错误数据。业务层是最糟糕的地方。

此外,当您用其他东西替换业务层时,您必须重新定义所有这些内容。数据库通常比它们多年来编写的原始应用程序更长久,将正确的实现和约束放在它们所属的数据库中。

答案 10 :(得分:1)

当您尝试将记录插入数据库并且参照完整性失败时会发生什么?您从数据库中收到错误。然后,您必须更改代码,以便它不会尝试插入无效数据。为避免引用完整性错误,您的代码必须知道哪些数据是哪些。因此,参照完整性是无用的。

Walter Mitty说:“为了验证新插入的参照完整性,您必须对数据库进行探测,以验证该引用是否有效。”叹息......这完全是胡说八道。如果我在会话中有一个Customer对象(即内存,也就是某些人的RAM),我知道客户的ID并可以使用它来插入SalesOrder对象。无需查询客户。

我现在使用的是一个系统,它具有严格的参照完整性和Hibernate以其粗糙的细节缠绕它。这是我见过的最慢的系统。我没有设计它,如果我有,它会快许多倍并且更容易维护。 Hibernate很糟糕。