【问题标题】:Would you ever create a relationship on a natural ID or use an internal ID and emulate the natural ID relationship? [duplicate]您是否会在自然 ID 上创建关系或使用内部 ID 并模拟自然 ID 关系? [复制]
【发布时间】:2011-01-06 21:54:47
【问题描述】:

可能重复:
Surrogate Vs. Natural/Business Keys

如果给定两个表,Level1 [ID, Title, Number] Level2 [ID, FKID???, Title, Number]

系统的用户知道 Level2 与 Level1 相关,基于 Level1 的 Number,我的问题是,你会根据内部 ID 建立关系并“模拟”与“Number”的关系,还是会只需使用“数字”字段即可完成?

【问题讨论】:

标签: database database-design foreign-key-relationship relationship


【解决方案1】:

在数据库 ID 而非自然 ID 上关联的两个标准原因是:

  1. 很难保证自然ID在任何情况下都不会改变
  2. 一般来说,自然 ID 占用更多空间,而且索引效率不如数据库 ID(当然,这并不难——它取决于构成自然 ID 的数据)。通过使用数据库 ID,您可以避免业​​务数据的重复。

【讨论】:

  • +1 完全正确!自然键很难永远真正保证是唯一和不可变的
  • 关于您的第二点,“避免重复业务数据”-为确保业务数据不重复,我们需要进行搜索-并且该搜索不能在代理键上,因为在用户的世界(即最终用户的世界) - 它是存在的自然密钥。在许多系统中,生成的代理密钥/序列对用户完全隐藏。最重要的是,即使在这些情况下,也需要查找自然键。我很想知道你对这种权衡的看法。
【解决方案2】:

这个讨论已经在这里被打死了。很少有人只保护自然键,大多数人鼓励使用代理键。有人说你可以两者兼得,当然这是真的(使用自然键,以便强制执行业务规则。)

如果自然键真的是键(大多数时候不是),我倾向于三思而后行。如果是,那我就用它。

但同样,现实中的大多数自然键都不是键,并且由于各种原因会出现重复。例如,在签发国民身份证的国家,发现两个人的身份证号码相同的情况并不少见。

也就是说,如果我要走代理键路线,我会像这样设置表格

Level1 [ID, Title, Number] Level2 [ID, FKID references Level1]

无需将标题和编号存储两次。

【讨论】:

    【解决方案3】:

    我想这已经被报道过很多次了。

    使用 IDENTITY/AUTONUMBER 作为外键几乎总是更安全。

    大多数自然键都可以复制(即使是错误的)。

    在我的国家,我们甚至对人的个人身份证号码 X-) 有问题。

    【讨论】:

      【解决方案4】:

      如果“数字”列可用于以自然方式关联两个表,我不会强制基于内部(代理)键的关系。

      一方面,“数字”列可能已经足够好,因此您不会在 ID 列上浪费空间。另一方面,如果“编号”列没有正确的特征(可能会更改、可能难以索引等),那么代理 ID 可能是更好的选择。

      这一切都归结为“数字”列的语义。

      【讨论】:

        【解决方案5】:
        • 有时最好使用天然的 if 键(例如 SSN 或 员工 ID)您可以放心 稳定性。

        • 使用代理键,FK 是 本质上是一种关系 系统生成#,到另一个系统 生成#。在极端情况下,例如 人为的关系可能是 与现实完全不同步。

        • 其他张贴者评论了当自然键必须更改时发生的混乱。当然那是个问题。但值得研究一下这些异常对你来说发生的频率——尾巴(异常)是否应该摇摆不定(你的设计)——在每种情况下?

        • 我对此并不狂热,但我同意在同一个数据库中使用自然键和代理键混合使用不同的约定很不方便。

        • 如果自然键是多个字段 ,说 DateOfBirth + LastName + 部门(或一些这样奇怪的 事情),那么你最好使用 人工钥匙。

        以上所有论点都处于数据模型的逻辑级别。在物理层面上,您的情况、服务器和性能限制将决定您的决定。最好不要过早优化。

        【讨论】:

        • 但是即使是 SSN 也不能保证是唯一的.....那么你想如何使用它作为主键呢???
        • 如果 SSN # 不是唯一的,则没有将其用作密钥的逻辑依据。也许这是一个不好的例子。相反,请考虑汽车上的 VIN #。您会使用 VIN 作为 PK,还是创建一个新的 ID 列?
        猜你喜欢
        • 1970-01-01
        • 2019-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-03
        • 2014-12-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多