你们认为呢?你们有什么经验?
编辑:请注意,我知道FK的作用和目标,我只是不确定它们是否会对像YouTube这样的Web应用程序的性能产生显着负面影响。
以下是InnoDB引擎的创建者,Innobase公司的创始人兼首席执行官Heikki Tuuri的一句话:
“在更新行时,InnoDB立即检查外键约束,不进行批处理或将检查延迟到事务提交。外键约束通常会对性能产生严重的开销,但有助于维护数据一致性。外键会增加行级锁定量,并可能使其传播到除直接更新的表之外的许多表。”
order_id
引用了orders
表的一个order_details
表,永远不会有一个不存在于orders
表中的order_id
值。
在关系型数据库中,外键并非必须,但它们绝对是避免破碎的关系和孤立行(即参照完整性)所必需的。在数据库层面上强制执行参照完整性是要求ACID中的C元素存在的。
至于你对性能的担忧,通常情况下,如果有的话,性能影响将是微不足道的。我建议在所有外键约束都放置好后,只有在您无法通过其他方式解决真正的性能问题时才进行实验。
此外,作为一个侧记,虽然与MySQL没有直接关系,但这是来自Microsoft Patterns and Practices: Chapter 14 Improving SQL Server Performance的引用:
"当主键和外键在数据库模式中定义为约束时,服务器可以使用该信息创建最佳执行计划。
保留您的外键-这可以确保无论谁为您编写代码,您的数据都保持在可用和预期的格式中。除非您面临严重的高流量问题,否则我甚至不会考虑删除它们。
网络应用程序与其他任何类型的应用程序没有区别。当然,你可能会因省略数据完整性检查而获得微小的加速,但这不会太明显,而且代价太高。
如果没有引用完整性,一旦出现悬空的外键(由于某些没有经过适当测试的代码路径或部分更新失败),很多查询都会失效,因为它们依赖于该键指向某个对象。这种情况非常常见,直到你深入数据库并手动删除悬空引用之前,整个网站都会崩溃。
(*:除非你正在使用事务。但让我们面对现实吧,如果你是那种不使用引用完整性的作者,你也不太可能使用事务。)
外键主要关乎完整性和功能,而非性能。如果您希望在两组列之间强制实施引用完整性,则通常使用外键是最有效和最有效的方法。如果您不需要支持这种完整性约束,则显然性能问题也不会出现。
外键可能通过支持某些类型的查询重写来提高性能,否则这些查询将无法实现。但是,这主要是一个附加好处 - 确保正在执行约束的副作用。
你的问题就像争论赛车不需要方向盘因为它会减速一样-毫无意义。所有的车辆都需要方向盘(至少现代的汽车是这样)。
其他人已经详细解释了外键对于数据完整性的有用性。
此外,我想指出,现代语言和框架可以使用数据库中的外键元数据来建立对象关系。Linq-to-SQL非常优雅地完成了这个任务。每当数据关系需要时,您实际上不能使用对象-关系映射框架而不定义外键。