【问题标题】:Pros and cons of programmatically enforcing foreign key than in database以编程方式强制执行外键比在数据库中的优缺点
【发布时间】:2010-04-01 00:56:06
【问题描述】:

仅仅让数据库强制执行外键在开发方面造成了很大的麻烦。特别是在单元测试期间,由于外键约束,我无法删除表,我需要按照不会触发外键约束警告的顺序创建表。实际上,我认为让数据库强制执行外键约束并没有太多意义。如果应用程序设计得当,除了选择查询之外,不应该有任何手动数据库操作。我只是想确保我不会因为在数据库中没有外键约束并将其完全交给应用程序负责而将自己挖到一个洞里。我错过了什么吗?

附:如果底层域对象的结构被修改,我真正的单元测试(不是那些使用模拟的)将删除现有的表。

【问题讨论】:

    标签: database foreign-keys


    【解决方案1】:

    根据我的经验,如果您不在数据库中强制执行外键,那么最终(假设数据库相对较大且使用率很高)您最终会得到孤立记录。这可能以多种方式发生,但似乎总是会发生。

    如果索引正确,外键应该不会有任何性能优势。

    所以问题是,在您的数据库中存在孤立记录的潜在损害/麻烦/支持成本/财务成本是否超过了开发和测试的麻烦?

    根据我的经验,对于业务应用程序,我总是使用外键。让您的构建脚本正常工作应该只是一次性的设置成本,并且数据稳定性将超过应用程序生命周期内的成本。

    【讨论】:

      【解决方案2】:

      在数据库中执行规则的重点是它是声明性的 - 例如您不必编写大量代码来处理它。

      就您的单元测试而言,只需按正确的顺序删除表即可。你只需要编写一个函数就可以完成一次。

      【讨论】:

      • 我正在考虑添加一个答案,但你说了需要说的话,所以你得到了赞成票。如果开发人员缺乏编写设置和重置脚本来准备测试先决条件的技术技能,那么他们不应该直接在数据库上操作。在这种情况下,DBA 应该准备这样的脚本。但是因为开发人员想偷懒而放弃参照完整性?不可能!
      【解决方案3】:

      您在开发中的问题不应推动数据库设计。不断重建数据库是开发人员用例,而不是客户用例。

      此外,数据库约束对您的应用程序也有帮助。您永远不知道您的客户可能会尝试做什么。不要过度,但你需要一些。

      【讨论】:

      • 这取决于您坚持的测试理论。根据 Roy Osherove 在他关于单元测试的书中的说法,编写良好的测试应该被认为是代码的合法用户。
      • @Kazark,但他们的需求不会取代数据用户的需求。以开发人员为中心的数据库设计是灾难的根源。没有任何条件可以让开发的便利性胜过数据的完整性。
      【解决方案4】:

      您似乎可以依靠您的应用程序来遵循隐含规则,但除非您最终强制执行这些规则,否则有人会犯错。
      或者也许从现在起 5 年后,有人会整理“不再需要”的旧记录,却没有意识到其他表中的数据仍在引用它们。然后几天/几周后,您或您的继任者会尝试修复数据库陷入的混乱局面。 :-)

      【讨论】:

      • 我在一家拥有大量客户记录和相关数据数据库的公司工作了 8 年,尽管有最好的意图,但各种事情都出了问题。人们在不完全了解数据库的情况下进行更改。任何你可以帮助他们避免犯错的帮助最终都会有回报
      【解决方案5】:

      在关于 SO 的上一个问题中对此进行了很好的讨论:What's wrong with foreign keys?。 [编辑]:如果有任何缺点适用,论点是制作非强制外键以获得一些优点。

      【讨论】:

        【解决方案6】:

        如果应用程序已正确 设计不应该有任何 手动数据库操作其他 而不是选择查询

        什么?你喝的是哪种koolaid?大多数数据库应用程序的存在是为了操作数据库中的数据,而不仅仅是为了查看它。通常,应用程序的全部目的是添加新订单或创建新客户记录或记录客户服务电话等。

        外键用于数据完整性。数据完整性对于能够以任何可靠性使用数据至关重要。没有数据完整性的数据库毫无用处,可能导致公司亏损。这胜过您以自我为中心的观点,即不需要 FK,因为它们使您的开发更加复杂。数据远比您在运行测试中的便利性重要得多(可以编写它来解释 FK)。

        【讨论】:

        • 是的,那是什么 koolaid?什么样的应用程序有独占只读的数据库
        猜你喜欢
        • 2011-09-14
        • 2017-05-08
        • 1970-01-01
        • 1970-01-01
        • 2010-09-07
        • 2011-03-02
        相关资源
        最近更新 更多