【问题标题】:How to choose my primary key?如何选择我的主键?
【发布时间】:2011-05-16 13:45:57
【问题描述】:

我在choosing a primary key找到了这份阅读材料。

  • 是否有关于如何为给定表选择主键的指南/博客文章?
  • 我应该使用自动递增/生成的键,还是应该将主键基于正在建模的数据(假设它具有真正唯一的字段)?
  • 为了性能起见,主键是否应该总是很长,或者我可以将外部唯一 id 作为主键,即使它是一个字符串?

【问题讨论】:

    标签: sql mysql database primary-key


    【解决方案1】:

    我使用代理键,通常称为无意义键,由自动生成的 int/bigint 数据类型组成。

    以下是我喜欢使用这些键的一些原因。

    • 从列表中删除多个项目(例如旧电子邮件)时,您可以提供逗号分隔的整数列表,而不是 guid 或自然键
    • 我发现它使编写自己的级联删除更容易
    • 我认为内连接在整数字段上更快
    • 它可以让学习一个没有文档的新系统更容易理解。

    【讨论】:

      【解决方案2】:

      键是一组具有两个基本特征的属性:唯一性和最小性。最小性意味着键只有确保唯一性所需的最少属性数。

      通常使用三个标准作为选择好键的指南:

      • 熟悉度 - 密钥对于使用它们的人来说应该是有意义和熟悉的
      • 简单 - 键应尽可能简单明了
      • 稳定性 - 关键值应不经常更改

      这些是很好的指导方针,但不是绝对要求。在所有情况下,功能需求和数据完整性需求都应确定使用哪些密钥。

      【讨论】:

        【解决方案3】:

        我相信在实践中使用natural key 很少比surrogate key 好。

        以下是使用自然键作为主键的主要缺点:

        • 您可能有一个不正确的键值,或者您可能只是想重命名一个键值。要对其进行编辑,您必须更新所有将其用作外键的表。

        • 通常很难拥有真正的unique 自然键。

        • 自然键通常是字符串。数字字段上的索引将比字符串字段上的索引更紧凑。

        对于主键的数据类型应该是什么没有硬性规定。数字键通常性能更好,但您可以使用字符串,尤其是在表不大且引用它的表也不大的情况下。

        【讨论】:

        • +1 - 在数据库中使用自然键和管理人员坚持重用客户 ID 的组合让我没有尽头,因为如果只有 12 个活跃的 Joe,他们不想要 joeblogs13博客……尽管它使所有可能的报告都出错,并在我们网站的每个页面上留下了竞争条件……
        • @Daniel Vassallo :所以您宁愿使用代理键而不是车辆的 VIN 代码或书籍的 ISBN 代码作为主键?这些代码符合 ISO 标准,您不认为如果处理行业问题,它们的效果会比代理键更好吗?
        • @Spredzy:在大多数情况下是的。我提到的第一点可能仍然很成问题。主键不是要更改的,您很容易在 ISBN 中出现拼写错误,您想修改......自然键通常会出现其他复杂情况,例如(引用from Wikipedia):“偶尔,如果一本书是私下印刷的,或者作者没有遵循通常的 ISBN 程序,这本书可能会出现没有印刷 ISBN 的情况;但是,这通常会在以后得到纠正”......这些例外情况很难处理......
        • ...我有时使用“国家”表的自然键,使用“ISO 3166-1”两个字母代码作为主键,但事后看来,即使这些偶尔也会发生变化。 . 代理键通常会让一切变得更简单。
        • 代理键不会阻止 ISBN 或国家/地区代码被复制。它也不允许数据库用户正确识别书籍和国家。从数据完整性和可用性的角度来看,选择熟悉、简单和稳定的密钥。表是否也有代理键在很大程度上是次要考虑因素,不应成为识别和实现键的决定性因素。
        【解决方案4】:

        我总是选择 uuid 作为主键。与 int/long key 相比,有一点点开销,但有很多好处:不会遇到类型溢出,以后可以在不更改主键的情况下对数据库进行分片,可以与其他系统集成并确保你的主键总是唯一的,uuid 不能被猜到等等。

        【讨论】:

        • -1 很抱歉投了反对票,但“总是选择 uuid”与“在适当时使用 uuid”4 字节 vs 36 - 嗯,填满缓冲区!!
        【解决方案5】:

        我曾在专业系统(主要是银行软件)中使用过许多不同的数据模型,并且有不同的解决方案。有我见过的 GUID 解决方案,它似乎并没有对性能产生太大影响。我已经看到“服务提供的号码作为系统范围的唯一号码”。我已经看到提供类似 GUID 的算法“但更短”。我还看到使用了业务密钥(如帐号),这是糟糕的设计并导致了问题,我不会推荐它。我已经看到每个表的自动递增键。

        我最喜欢什么?服务提供的号码作为系统范围的号码。它运作良好。并且使用简单的键转换表,可以使用用户键(如帐号)找出唯一编号和数据对象类型(不一定是表,因为如果一个数据对象,相同的唯一键可能适用于多个表根据其类型分为不同的表)。

        那么有博客之类的吗?好吧,我有一本值得推荐的书,名为 Graeme Simsion 和 Graham Witt 的《数据建模要点》。他们可能不会建议我首选的解决方案,但他们提供了许多真实的示例,并展示了可能的不同类型的解决方案。

        【讨论】:

          【解决方案6】:
          猜你喜欢
          • 2019-06-24
          • 1970-01-01
          • 1970-01-01
          • 2011-09-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-23
          • 2015-01-16
          相关资源
          最近更新 更多