据我所知,外键(FK)用于帮助程序员以正确的方式操作数据.假设程序员实际上已经以正确的方式执行此操作,那么我们真的需要外键的概念吗?
外键还有其他用途吗?我在这里错过了什么吗?
外键有助于在数据级别强制引用完整性.它们还可以提高性能,因为它们通常默认为索引.
外键还可以帮助程序员使用类似的东西编写更少的代码ON DELETE CASCADE
.这意味着如果您有一个包含用户的表和另一个包含订单或其他内容的表,则删除用户可以自动删除指向该用户的所有订单.
我无法想象没有外键设计数据库.没有它们,最终你一定会犯错误并破坏数据的完整性.
严格来说,它们不是必需的,但是它们的好处是巨大的.
我很确定FogBugz在数据库中没有外键约束.我很想知道Fog Creek Software团队如何构建他们的代码以保证他们永远不会引入不一致.
没有FK约束的数据库模式就像没有安全带的驾驶一样.
有一天,你会后悔的.不花费那么多时间在设计基础和数据完整性上,这是确保后期头痛的可靠方法.
你会接受你的应用程序中那些草率的代码吗?直接访问成员对象并直接修改数据结构.
为什么你认为这在现代语言中变得困难甚至是不可接受的?
是.
他们让你诚实
他们让新开发者保持诚实
你可以做 ON DELETE CASCADE
它们可以帮助您生成可以自我解释表之间链接的漂亮图表
就个人而言,我赞成外键,因为它正式化了表之间的关系.我意识到你的问题预先假定程序员没有引入会违反参照完整性的数据,但是我已经看到了太多违反数据参照完整性的情况,尽管有最好的意图!
前外键约束(也称为声明性引用完整性或DRI)花费了大量时间来使用触发器实现这些关系.我们可以通过声明性约束来形式化关系这一事实非常强大.
@John - 其他数据库可能会自动为外键创建索引,但SQL Server不会.在SQL Server中,外键关系仅是约束.您必须单独在外键上定义索引(这可能是有益的.)
编辑:我想补充一点,IMO,使用外键支持ON DELETE或ON UPDATE CASCADE不一定是件好事.在实践中,我发现应该根据数据的关系仔细考虑删除级联 - 例如,你是否有一个自然的亲子,这可能是好的,或者是相关的表是一组查找值.使用级联更新意味着您允许修改一个表的主键.在这种情况下,我有一个普遍的哲学分歧,因为表的主键不应该改变.键应该是固有的.
假设程序员实际上已经以正确的方式执行此操作
在我看来,做出这样的假设是一个非常糟糕的主意; 一般来说,软件是非常错误的.
这就是重点,真的.开发人员无法把事情弄清楚,因此确保数据库不能填充不良数据是一件好事.
虽然在理想的世界中,自然连接会使用关系(即FK约束)而不是匹配列名.这将使FK更加有用.
如果没有外键,您如何判断不同表中的两条记录是否相关?
我认为你所指的是参照完整性,其中不允许在没有现有父记录的情况下创建子记录等.这些通常被称为外键约束 - 但是不要与外键的存在混淆.第一名.
没有外键有没有好处?除非您使用的是蹩脚的数据库,否则FK并不难设置.那你为什么要有避免它们的政策呢?如果有一个命名约定说明一个列引用了另一个,那么另一个就是知道数据库实际上正在为你验证这种关系.
我想你在谈论数据库强制执行的外键约束.您可能已经在使用外键,您只是没有告诉数据库它.
假设程序员实际上已经以正确的方式执行此操作,那么我们真的需要外键的概念吗?
从理论上讲,没有.但是,从来没有一个没有错误的软件.
应用程序代码中的错误通常不那么危险 - 您确定错误并修复它,然后应用程序再次顺利运行.但如果一个错误允许破解数据进入数据库,那么你就会陷入困境!从数据库中的损坏数据中恢复非常困难.
考虑一下FogBugz中的一个微妙的错误是否允许在数据库中写入损坏的外键.修复错误可能很容易,并在修补程序版本中快速将修复程序推送给客户.但是,如何修复数十个数据库中的损坏数据呢?正确的代码现在可能会突然中断,因为关于外键完整性的假设不再存在.
在Web应用程序中,您通常只有一个程序与数据库通信,因此只有一个地方可以破坏数据.在企业应用程序中,可能有几个独立的应用程序与同一个数据库通信(更不用说直接使用数据库shell的人).没有办法确保所有应用程序遵循相同的假设,没有错误,永远和永远.
如果在数据库中对约束进行编码,则错误可能发生的最坏情况是向用户显示关于某些SQL约束不满意的丑陋错误消息.这更容易让数据被破坏到您的企业数据库中,反过来它会破坏您的所有应用程序,或者只会导致各种错误或误导性的输出.
哦,外键约束也提高了性能,因为它们默认是索引的.我想不出任何不使用外键约束的理由.
FK非常重要,应该始终存在于您的架构中,除非您是eBay.
我认为在某些时候某些事情必须负责确保有效的关系.
例如,Ruby on Rails不使用外键,但它会验证所有关系本身.如果您只从Ruby on Rails应用程序访问您的数据库,这很好.
但是,如果您有其他客户端正在写入数据库,那么没有外键,他们需要实现自己的验证.然后,您有两个验证代码的副本,这些副本很可能是不同的,任何程序员都应该能够告诉它是一个主要的罪.
此时,外键确实是必要的,因为它们允许您再次将责任移到单个点.
外键允许之前没有看过您的数据库的人确定表之间的关系.
现在一切都很好,但想想当你的程序员离开而其他人必须接管时会发生什么.
外键将允许他们理解数据库结构,而无需拖拽数千行代码.
据我所知,外键用于帮助程序员以正确的方式操作数据.
当程序员没有这样做时,FK允许DBA保护数据完整性免受用户笨拙的影响,有时可以防止程序员的笨手笨脚.
假设程序员实际上已经以正确的方式执行此操作,那么我们真的需要外键的概念吗?
程序员是凡人和易犯错误的.FK是声明性的,这使得它们更难搞砸.
外键还有其他用途吗?我在这里错过了什么吗?
虽然这不是创建它们的原因,但FK为图表工具和查询构建器提供了强有力的可靠提示.这将传递给最终用户,他们迫切需要强大可靠的提示.