【问题标题】:Numeric IDs vs. String IDs数字 ID 与字符串 ID
【发布时间】:2023-04-03 22:52:01
【问题描述】:

我在这里使用了一个非常精简的示例,所以请询问您是否需要更多上下文。

我正在重组/规范化数据库,其中大多数表中的 ID 字段都有主键字段,这些字段是自动递增的数字 ID(1、2、3 等),我在想我需要将 ID 字段从数值更改为从行中的数据生成的字符串值。

我的理由如下:

我有 5 张桌子;工作人员、会员、志愿者、实习生和学生;所有这些都有数字 ID。

我有另一个名为 BuildingAttendance 的表,它记录人们何时访问该场所以及出于什么原因,其中包含以下相关字段:

ID    Type    Premises    Attended

区分员工和成员。我使用类型字段,成员使用 MEM,员工使用 STA,等等。例如:

ID    Type    Premises      Attended
1     MEM     Building A    27/6/15
1     STA     Building A    27/6/15
2     STU     Building B    27/6/15

我认为使用类似于以下的 ID 可能是更好的设计设计:

ID       Premises      Attended
MEM1     Building A    27/6/15
STA1     Building A    27/6/15
STU2     Building B    27/6/15

解决这个问题的最佳方法是什么?我知道如果我的主键是一个字符串,我的查询性能可能会受到影响,但这比拥有 2 列更容易吗?

tl;dr - 我应该如何处理引用来自具有相同 ID 系统的其他表的记录的表?

【问题讨论】:

  • 如果你的 ID 字段是一个聚集的主键,那么连接字符串值是个坏主意。看看这篇文章。 simple-talk.com/sql/learn-sql-server/…
  • 在您的示例中,您认为哪种方法可以让您更轻松地处理将状态从员工更改为成员的人,反之亦然?
  • @DanBracuk,很少有人会从成员变为员工。 (即在过去的 2 年里,我们只有 3 人这样做。)我不确定哪个更好,我只是想找出哪个性能更好。
  • 如果你现在正在重组,为什么不创建一个表 Person,具有唯一 id 和公共属性,以及具有外键 person id 和的 Staff、Members 等不同(子)表只有正确的字段?
  • 是的,这应该是一个很好的设计,这样您就可以在通用表中放置一个“类型”属性,然后在 BuildingAttendance 中只放置 Personnel 表的外键。这是解决此类问题的标准方法。

标签: sql database-design normalization


【解决方案1】:

自动递增的数字 ID 比字符串有几个优点:

  • 它们更易于实施。为了生成字符串(如您所愿),您需要实现触发器或计算列。
  • 它们占用固定数量的存储空间(可能是 4 个字节),因此它们在数据记录和索引中的效率更高。
  • 它们允许成员在类型之间进行更改,而不会影响键。

您面临的问题是您有超类型的子类型。此信息应与一起存储,而不是在出勤记录中(除非一个人可以在每次访问时更改他们的类型)。在 SQL 中有几种方法可以解决这个问题,没有一种方法比编程语言中的简单类继承更简洁。

一种技术是将所有数据放在一个名为Persons 的表中。这将有一个唯一的 id、一个类型和五个表中的所有列。问题是当您的子表中的列非常不同时。

在这种情况下,有一个名为 people 的表,它具有唯一的主键和公共列。然后为每个表创建单独的表,并使用PersonId 作为这些表的主键。

这种方法的优点是您可以有一个对Persons 的外键引用,例如BuildingAttendance。而且,您还可以在适当的情况下为其他表提供对每个子类型的外键引用。

【讨论】:

    【解决方案2】:

    Gordon Linoff 已经提供了一个答案,指出了类型/超类型问题。我将其称为类/子类,但这只是术语上的差异。

    这个区域有两个标签收集与类/子类相关的问题。他们在这里:

    如果您查看每个标签的信息选项卡,您会看到一个简短的大纲。加上问题的答案将帮助您处理您的案件。

    通过创建一个名为 Person 的带有自动编号 ID 的表,您可以方便地引用一个人,而不管该人的类型如何。通过让工作人员、成员、志愿者、学生和实习生表使用此 ID 的副本作为他们自己的 ID,您将促进您需要执行的任何联接。

    关于是否在考勤中包含类型的决定取决于您是要使用人员当前类型还是使用人员在出勤时的类型检索数据。

    【讨论】:

      猜你喜欢
      • 2011-02-02
      • 1970-01-01
      • 2022-10-13
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 2015-07-15
      • 1970-01-01
      • 2014-01-25
      相关资源
      最近更新 更多