数字ID与字符串ID

时间:2015-09-30 09:19:21

标签: sql database-design normalization

我在这里使用了一个非常精简的示例,请询问您是否需要更多背景信息。

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

我的理由如下:

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

我有另一个名为import tornado.ioloop io_loop = tornado.ioloop.IOLoop.current() 的表,当人们访问该处所时会记录该表,并且出于什么原因有以下相关字段:

BuildingAttendance

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

ID    Type    Premises    Attended

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

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

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

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

2 个答案:

答案 0 :(得分:3)

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

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

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

一种技术是将所有数据放在一个名为{ "key": "actions", "notitle": true, "properties": { "key": "singleSelection", "notitle": true, "startEmpty": true } }, 的表中。这将有一个唯一的id,类型和五个表中的所有列。问题是子表中的列非常不同。

在这种情况下,请创建一个名为people的表,该表具有唯一的主键和公共列。然后为每个表分别使用表格,并使用Persons作为这些表的主键。

这种方法的优点是,您可以使用PersonId的外键引用Persons。并且,您还可以为每个子类型提供外键引用,适用于其他表。

答案 1 :(得分:1)

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

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

如果您要查看每个标记的信息标签,您会看到一个简短的大纲。此外,问题的答案将帮助您解决问题。

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

关于是否包括出席类型的决定取决于您是否要使用此人的当前类型或该人在出席时所具有的类型来检索数据。