使用项目特定的前缀和自动编号为主键?

时间:2009-02-03 06:16:57

标签: database-design primary-key

我们今天早上开了一个会议,讨论如何将我们的ID存储在我们正在制作的数据库中的某些资产中,这些描述产生了一些热量,所以我决定咨询SO的专家。

我认为我们应该拥有的表格结构(简短版本)如下所示:

示例1)

  • AssetId - int(32) - 主键
  • 类型 - 字符串

所以一些示例数据是这样的:

==AssetId======Type===
  12345        "Manhole"
  155415       "Pit"

团队的另一名成员提出了类似的建议:

示例2)

  • AssetId - 字符串 - 主键
  • 类型 - 字符串

所以一些示例数据是这样的:

==AssetId======Type===
  "MH12345"    "Manhole"
  "P155415"    "Pit"

我们制作该类型的简短版本并将其附加到ID的前面并将其存储在数据库中。我已经看到一些资产数据库这样做,从来没有真正的这种方法。

我从未真正喜欢将字符串用作ID以进行排序的原因。当你已经拥有资产商店的类型时,我也觉得存储无用的信息只是为了它。

你会采取什么方法?为什么?使用方法1超过2有什么好处吗?

编辑:是的我将使用AUTO_INCREMENT进行方法1。

9 个答案:

答案 0 :(得分:25)

通常,经验法则是永远不要在主键中使用有意义的信息(如社会安全号码或条形码)。只是简单的自动增量整数。 然而,数据似乎不变 - 它可能会在某一时刻发生变化(新立法到来,所有SSN都会重新计算)。

答案 1 :(得分:7)

这是surrogate and natural keys之间的决定,第一个是代理(或“技术”),第二个是自然的。

我得出的结论是,你应该总是使用代理键。如果你使用自然键,那些可能会改变,更新主键/外键通常不是一个好主意。

答案 2 :(得分:4)

我会选择前者。创建唯一ID应留给SQL服务器,如果它们是字符串,则不能以线程安全的方式自动创建。根据我的理解,你必须以某种方式自己处理它?<​​/ p>

速度是另一个因素。处理int值总是比字符串快。我会说索引还有其他好处,比我更精明的SQL人员可以详细说明;)

根据我的经验,拥有字符串ID是失败的。

答案 3 :(得分:3)

好吧,我想提出一些观点和建议,

  • 考虑为Type设置一个单独的表,比如列Id和Desc,然后在此表中创建一个外键TypeId。更进一步,以规范事物。但它可能不可取。如果您认为它有用的话,请这样做

  • 使它成为字符串确实有意义,如果以后你们想到转向UUID。您无需更改数据类型

<强> [编辑]

我同意Cletus的观点。事实证明,这个代理关键在一些现实生活中是有益的。它们允许变化,你知道变化是唯一不变的。

答案 4 :(得分:3)

出于性能原因,我会选择数字主键。整数比较比字符串比较便宜得多,并且它将在DB中占用更少的空间。

答案 5 :(得分:2)

我个人认为第一种方法远远好得多。它允许数据库软件进行简单的整数比较,以便按键查找和排序,这将提高表操作性能(SELECT,复杂JOIN,按键INDEX查找等)。

当然,我假设无论哪种方式,你都在使用某种自动递增方法来产生ID - 序列,AUTO_INCREMENT或类似的东西。请帮个忙,不要在你的程序代码中构建它们,好吗?

答案 6 :(得分:1)

我更喜欢示例1,因为你提到的原因和我能想到的唯一一个使用示例2的论点是你是否试图从现有数据库中容纳字符串ID(很常见),但即使在那种情况下,我更喜欢使用以下方法。

==AssetId(PK)==Type========DeprecatedId====
  12345        "Manhole"   "MH64247"
  155415       "Pit"       "P6487246"

答案 7 :(得分:0)

如果您的资产已经拥有唯一的自然标识符(例如员工拥有其员工ID),请使用它们。创建另一个唯一标识符毫无意义。

另一方面,如果没有自然唯一ID,请使用最短的ID,以确保足够的唯一键用于预期的表大小(例如整数)。它需要更少的磁盘空间并且可能更快。此外,如果您发现自己以后需要使用基于字符串的密钥,那么这是一个简单的替换工作:

  • 将sting主键添加到资产表。
  • 将字符串外键添加到引用表。
  • 使用整数关系使用简单的UPDATE命令更新字符串关系。
  • 为sting列添加外键约束。
  • 删除整数列的外键约束。
  • 完全删除整数列。

其中一些步骤可能在特定的DBMS上存在问题,可能需要使用表卸载/重新加载来删除整数主键列,但该策略基本上是所需的。

答案 8 :(得分:0)

示例2的唯一优点是,您可以轻松地仅从主键中分辨出此键适用于哪个表的哪一行。这个想法很好,但它是否有用取决于您的日志记录和错误消息策略。它可能具有性能劣势,因此我不会使用它,除非您可以列举使用它的一些具体原因。

(你也可以通过使用全局序列生成数字键,或使用不同的数字范围,最后的数字或其他任何东西来获得这个优势。那么你没有性能劣势,但也许你找不到表很容易。)