据我所知,外键(FK)用于帮助程序员以正确的方式操作数据。假设程序员实际上已经在以正确的方式执行此操作,那么我们真的需要外键的概念吗?
外键还有其他用途吗?我在这里想念什么吗?
据我所知,外键(FK)用于帮助程序员以正确的方式操作数据。假设程序员实际上已经在以正确的方式执行此操作,那么我们真的需要外键的概念吗?
外键还有其他用途吗?我在这里想念什么吗?
Answers:
外键有助于在数据级别上实现引用完整性。它们还提高了性能,因为通常默认情况下对它们进行索引。
外键还可以帮助程序员使用诸如之类的代码编写更少的代码ON DELETE CASCADE
。这意味着,如果您有一个包含用户的表,而另一个包含订单或其他东西的表,那么删除用户可以自动删除所有指向该用户的订单。
我无法想象设计没有外键的数据库。没有它们,最终您必定会犯一个错误并破坏数据的完整性。
严格来讲,它们不是必需的,但是好处是巨大的。
我相当确定FogBugz在数据库中没有外键约束。我想听听Fog Creek软件团队如何构建代码以确保他们永远不会引入不一致之处。
是。
ON DELETE CASCADE
就个人而言,我赞成使用外键,因为它使表之间的关系正式化。我意识到您的问题以程序员没有引入会破坏参照完整性为前提的数据为前提,但是我看到了太多的例子,尽管有最好的意图,但这些数据违反了参照完整性。
前外键约束(又称为声明性引用完整性或DRI)花费了大量时间使用触发器来实现这些关系。我们可以通过声明性约束将关系形式化的事实非常有力。
@John-其他数据库可能会自动为外键创建索引,但是SQL Server不会。在SQL Server中,外键关系仅是约束。您必须分别在外键上定义索引(这很有用。)
编辑:我想补充一点,IMO,使用外键来支持ON DELETE或ON UPDATE CASCADE不一定是一件好事。在实践中,我发现应该根据数据之间的关系仔细考虑级联删除操作,例如,您是否有一个自然的父子级关系,或者相关表是一组查找值?使用级联更新意味着您允许修改一个表的主键。在那种情况下,我有一个普遍的哲学分歧,那就是表的主键不应更改。键本质上应该是恒定的。
我想您正在谈论数据库强制执行的外键约束。您可能已经在使用外键,只是没有告诉数据库。
假设程序员实际上已经在以正确的方式执行此操作,那么我们真的需要外键的概念吗?
从理论上讲,不会。但是,从来没有一款软件没有错误。
应用程序代码中的错误通常没有那么危险-确定并修复该错误,然后应用程序可以再次平稳运行。但是,如果一个错误允许不可靠的数据进入数据库,那么您就被它困住了!从数据库中的损坏数据中恢复非常困难。
考虑一下FogBugz中的一个细微错误是否允许将损坏的外键写入数据库。修正错误并在修正版本中快速将修正推向客户很容易。但是,如何解决数十个数据库中的损坏数据?正确的代码现在可能突然中断,因为关于外键完整性的假设不再成立。
在Web应用程序中,通常只有一个程序与数据库对话,因此,只有一个地方错误可能破坏数据。在企业应用程序中,可能有几个独立的应用程序与同一个数据库对话(更不用说直接与数据库外壳一起工作的人了)。没有办法确保所有应用程序都遵循相同的假设,并且始终存在错误。
如果约束是在数据库中编码的,则错误可能发生的最糟糕的情况是,向用户显示关于某些SQL约束未满足的丑陋错误消息。这是很多 prefereable又让currupt数据到企业数据库,它反过来会打破所有的应用程序,或只是导致各种错误或误导性的输出。
哦,外键约束也可以提高性能,因为默认情况下会对其进行索引。我想不出任何理由不使用外键约束。
我认为某些时候某些事情必须负责确保有效的关系。
例如,Ruby on Rails不使用外键,但是它会验证所有关系本身。如果您只从该Ruby on Rails应用程序访问数据库,那很好。
但是,如果您有其他正在写入数据库的客户端,则没有外键,它们需要实现自己的验证。然后,您将获得验证码的两个副本,它们很可能是不同的,任何程序员都应该知道这是一个主要的罪过。
到那时,确实需要外键,因为它们使您可以将职责再次移至单个点。
据我所知,外键用于帮助程序员以正确的方式操作数据。
FK允许DBA在程序员未这样做时保护数据完整性,以防止用户感到困惑,有时还可以防止程序员感到困惑。
假设程序员实际上已经在以正确的方式执行此操作,那么我们真的需要外键的概念吗?
程序员是凡人,容易犯错误。FK是声明性的,这使它们更难搞砸。
外键还有其他用途吗?我在这里想念什么吗?
尽管这不是创建它们的原因,但是FK为图表工具和查询生成器提供了可靠的可靠提示。这将传递给最终用户,他们迫切需要强大的可靠提示。
我从成本/收益方面考虑...在MySQL中,添加约束是DDL的另外一行。这只是几个关键词和几秒钟的思考。我认为这是唯一的“成本”。
工具喜欢外键。外键可防止可能不会影响业务逻辑或功能的不良数据(即孤立的行),因此不会引起注意并堆积。这还可以防止不熟悉该架构的开发人员实现整个工作块,而不会意识到他们之间缺少关系。也许在当前应用程序的范围内,一切都很好,但是如果您错过了某些东西,并且有一天又添加了一些意外的东西(想想报告),您可能就需要手动清理自开始以来就积累的不良数据。无需数据库强制检查的模式。
将事情整理在一起时,花很少的时间整理头脑中已有的内容,可以为您或其他人节省数月或数年的痛苦。
问题:
外键还有其他用途吗?我在这里想念什么吗?
它有点加载。插入注释,缩进或变量命名来代替“外键” ...如果您已经完全理解了所要解决的问题,那么这对您“毫无用处”。
熵减少。减少数据库中发生混乱情况的可能性。考虑到所有可能的目标,我们都遇到了困难,因此,我认为,减少熵是维护任何系统的关键。
例如,当我们进行假设时:每个订单都有一个客户,该假设应由某种东西来执行。在数据库中,“某物”是外键。
我认为这值得在开发速度上进行权衡。当然,您可以在不使用它们的情况下更快地编写代码,这可能就是为什么某些人不使用它们的原因。就我个人而言,我已经使用NHibernate消磨了几个小时,并且某些外键约束在执行某些操作时会很生气。但是,我知道问题出在哪里,所以问题不大。我使用的是常规工具,并且有很多资源可以帮助我解决此问题,甚至可能有人需要帮助!
替代方法是允许错误爬入未设置外键且数据变得不一致的系统中(并且有足够的时间,它将进入系统)。然后,您将得到一个异常的错误报告,进行调查并“ OH”。数据库被搞砸了。现在要花多长时间才能解决?
我们目前不使用外键。在大多数情况下,我们不后悔。
话虽如此-我们出于各种原因可能会在不久的将来开始大量使用它们,而这两个原因都有相似之处:
图解。如果正确使用了外键关系,那么生成数据库图表就容易得多。
工具支持。如果存在适当的外键关系,则使用Visual Studio 2008建立可用于LINQ to SQL的数据模型要容易得多。
所以我想我的意思是,我们发现,如果我们在做大量手动SQL工作(构造查询,运行查询,等等),外键不一定是必需的。但是,一旦您开始使用工具,它们就会变得有用得多。
关于外键约束(实际上确实是约束)的最好之处在于,编写查询时可以依赖它们。如果您不依赖于数据模型为“ true”,那么很多查询就会变得更加复杂。
在代码中,通常只会在某处引发异常-但是在SQL中,通常只会得到“错误”答案。
从理论上讲,SQL Server可以将约束用作查询计划的一部分-但是除了用于分区的检查约束之外,我不能说我曾经亲眼目睹过。
我从事过的项目(业务应用程序和社交网站)中从未声明过外键(FOREIGN KEY REFERENCES表(列))。
但是,总是有一种命名列的约定,即外键。
就像数据库规范化一样,您必须知道自己在做什么以及这样做的结果(主要是性能)。
我知道外键的优点(数据完整性,外键列的索引,知道数据库模式的工具),但是我也害怕将外键用作一般规则。
同样,各种数据库引擎可以以不同的方式提供外键,这可能会导致在迁移过程中产生细微的错误。
使用ON DELETE CASCADE删除已删除客户端的所有订单和发票是外观漂亮但设计错误的数据库架构的完美示例。