表中主键的最佳做法是什么?

在设计表格时,我养成了一种习惯,即让一列是唯一的,而且我是主键。 这取决于要求以三种方式实现:

  • 自动递增的标识整数列。
  • 唯一标识符(GUID)
  • 可用作行标识符列的短字符(x)或整数(或其他相对较小的数字类型)列
  • 数字3将用于相当小的查找,主要是读取表格,可能具有唯一的静态长度字符串代码或数字值,如年份或其他数字。

    大多数情况下,所有其他表都将具有自动递增整数或唯一标识符主键。

    问题:-)

    我最近开始使用没有一致行标识符的数据库,并且主键当前正在跨各个列进行群集。 一些例子:

  • 日期时间/字符
  • 日期时间/整数
  • 日期时间/ VARCHAR
  • 炭/ NVARCHAR / nvarchar的
  • 这有没有一个有效的案例? 我会一直为这些情况定义一个身份或唯一标识符列。

    另外还有很多没有主键的表格。 有什么有效的理由,如果有的话?

    我试图理解为什么桌子是按照原样设计的,这对我来说似乎是一个很大的混乱,但也许有充分的理由。

    第三个问题有助于我解释答案:在多列用于组成复合主键的情况下,这种方法与代理/人工密钥相比有没有特定的优势? 我主要在考虑性能,维护,管理等方面?


    我遵循一些规则:

  • 主键应尽可能小。 因为数字类型以比字符格式更紧凑的格式存储,所以首选数字类型。 这是因为大多数主键在另一个表中都是外键,以及在多个索引中使用。 您的密钥越小,索引越小,您将使用的缓存中的页面越少。
  • 主键不应该改变。 更新主键应该始终是不可能的。 这是因为它最有可能用于多个索引并用作外键。 更新单个主键可能会导致更改的连锁反应。
  • 不要使用“你的问题主键”作为你的逻辑模型主键。 例如护照号码,社会安全号码或雇员合同号码,因为这些“主键”可以针对真实世界的情况而改变。
  • 关于代理与自然关键,我参考上述规则。 如果自然键很小并且永远不会改变,它可以用作主键。 如果自然键很大或可能改变,我使用代理键。 如果没有主键,我仍然使用代理键,因为经验表明,您将始终向表中添加表并希望将主键置于原位。


    自然经文人造密钥是数据库社区中的一种宗教争论 - 请参阅本文及其链接的其他内容。 我既不赞成总是拥有人造钥匙,也永远不拥有它们。 我会根据具体情况决定,例如:

  • 美国:我会去state_code(德克萨斯等的'TX'),而不是德克萨斯州的state_id = 1
  • 员工:我通常会创建一个artifical employee_id,因为很难找到其他任何可行的工具。 SSN或同类产品可能有效,但可能存在诸如尚未提供其SSN的新木工等问题。
  • 员工薪资记录:(employee_id,start_date)。 我不会创建一个人造的employee_salary_history_id。 它会发挥什么作用(除了“愚蠢的一致性”)
  • 无论使用哪个仿真键,您都应该始终在自然键上声明唯一的约束。 例如,如果你必须使用state_id,但是你最好在state_code上声明一个唯一的约束,否则你最终肯定会得到:

    state_id    state_code   state_name
    137         TX           Texas
    ...         ...          ...
    249         TX           Texas
    

    只是对经常被忽视的东西进行额外的评论。 有时不使用代理键在子表中有好处。 假设我们有一个允许您在一个数据库中运行多个公司的设计(也许它是一个托管解决方案,或其他)。

    假设我们有这些表格和列:

    Company:
      CompanyId   (primary key)
    
    CostCenter:
      CompanyId   (primary key, foreign key to Company)
      CostCentre  (primary key)
    
    CostElement
      CompanyId   (primary key, foreign key to Company)
      CostElement (primary key)
    
    Invoice:
      InvoiceId    (primary key)
      CompanyId    (primary key, in foreign key to CostCentre, in foreign key to CostElement)
      CostCentre   (in foreign key to CostCentre)
      CostElement  (in foreign key to CostElement)
    

    如果最后一位没有意义, Invoice.CompanyId是两个外键的一部分,一个是CostCentre表,另一个是CostElement表。 主键是(InvoiceId,CompanyId)。

    在这个模型中,不可能将一个公司的CostElement和另一个公司的CostCentre引用并引用。 如果在CostElement和CostCentre表上使用代理键,则会是。

    糟糕的机会越少越好。

    链接地址: http://www.djcxy.com/p/59309.html

    上一篇: What's the best practice for primary keys in tables?

    下一篇: Rubocop 25 line block size and RSpec tests