【问题标题】:What's a foreign key for?外键有什么用?
【发布时间】:2013-01-01 05:45:06
【问题描述】:

我一直在使用与 SQL (MySQL) 和 Rails 的表关联没有问题,而且我从来不需要指定外键约束。

我只是在 belongs_to 表中添加了一个 table_id 列,一切正常。

那么我错过了什么?在 MySQL 或其他 RDBMS 中使用外键子句有什么意义?

谢谢。

【问题讨论】:

    标签: sql ruby-on-rails database


    【解决方案1】:

    外键是两个表之间的引用约束

    外键约束存在的原因是为了保证引用的行存在。

    外键标识一个(引用或子)表中的一列或一组列,它引用另一个(引用或父)表中的一列或一组列。

    • 您可以获得良好的“删除级联”行为,自动清理表

    这里列出了很多使用外键的原因:Why Should one use foreign keys

    【讨论】:

    • 所以我想跟进(尽管您的回复中几乎暗示了)是......真的值得吗?
    【解决方案2】:

    Rails(更具体地说是ActiveRecord自动猜测你的外键。

    ...默认情况下,这被猜测为带有“_id”后缀的关联名称。

    外键强制参照完整性

    外键:表中的一列或一组列,其值需要与另一个表的一行的至少一个 PrimaryKey 值匹配。

    另见:

    【讨论】:

      【解决方案3】:

      外键或任何引用约束的基本思想是数据库不应允许您存储明显无效的数据。它是数据一致性的核心组件,ACID rules之一。

      如果您的数据模型表明您可以将多个电话号码与一个帐户关联,您可以将电话表定义为需要一个有效的帐号。因此,无法存储孤立的电话记录,因为您无法在没有有效帐号的情况下在电话表中插入一行,并且您无法在不先删除电话号码的情况下删除帐户。如果该字段是生日,您可能会强制要求日期早于明天的日期。如果字段是高度,您可以强制距离在 30 到 4000 厘米之间。这意味着任何应用程序都不可能在数据库中存储无效数据。

      “好吧,为什么我不能把所有这些都写到我的应用程序中?”你问。对于单应用程序数据库,您可以。但是,任何拥有存储用于业务运营的数据的重要数据库的企业都希望直接访问数据。他们希望能够从财务或 HR 导入数据,或将地址导出到销售,或通过从 Active Directory 导入它们来创建应用程序用户帐户等。对于非平凡的应用程序,用户的数据 em> 是重要的,这就是他们想要访问的。在某些时候,他们会希望在您的应用程序代码不妨碍的情况下访问他们的数据。这是 RDMBS 的真正力量和优势,也是使系统集成成为可能的原因。

      但是,如果您的所有规则都存储在应用程序中,那么您的用户将需要非常小心他们如何操作数据库,以免导致应用程序崩溃。如果您指定关系约束和参照完整性,则需要其他应用程序以对任何将要使用它的应用程序有意义的方式修改数据。逻辑与数据(它所属的位置)而非应用程序相关联。

      请注意,MySQL is absolute balls 与参照完整性有关。当您尝试将空日期插入具有约束not null default null 的日期时间字段时,它往往会默默地成功而不是抛出错误,通常是通过插入明显无效的值(例如今天的日期时间)。 DBA 说 MySQL 是个笑话是有充分理由的。

      【讨论】:

        【解决方案4】:

        外键强制执行referential integrity。外键约束将防止您或任何其他用户在表中错误地添加不正确的记录。它确保在外键中输入的数据 (ID) 确实存在于引用表中。如果一些错误的客户端代码试图插入不正确的数据,那么在外键约束的情况下会引发异常,否则如果约束不存在,那么您的数据库将最终得到不一致的数据。

        【讨论】:

          【解决方案5】:

          我能想到的使用外键的一些好处:

          • 使表间数据保持一致,防止出现不良数据(例如表A有一些记录引用表B中不存在的东西)

          • 帮助记录我们的数据库

          • 有些框架是基于外键生成领域模型

          【讨论】:

          • 虽然提到了性能下降.. 这个呢?
          • 插入、更新和删除对性能有一点影响,因为必须检查 FK。但从长远来看,大型项目,我认为没有理由不使用 FK
          猜你喜欢
          • 2012-01-25
          • 2016-05-25
          • 2011-03-26
          • 2012-04-28
          • 1970-01-01
          • 2016-05-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多