12

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

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

示例 1)

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

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

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

等等

团队的另一位成员提出了这样的建议:

例 2)

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

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

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

我们制作一个简短版本的类型并将其附加到 ID 的前面并将其存储在数据库中。我见过一些这样做的资产数据库,但从未真正采用过这种方法。

由于排序原因,我从来没有真正喜欢过使用字符串作为 ID 的想法。我也觉得当你已经拥有资产商店的类型时,它只是为了它而存储无用的信息。

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

编辑:是的,我将在方法 1 中使用 AUTO_INCREMENT。

4

9 回答 9

26

通常经验法则是永远不要在主键中使用有意义的信息(如社会安全号码或条形码)。只是普通的自动递增整数。无论数据看起来多么稳定 - 它可能会在某一时刻发生变化(新立法出台,所有 SSN 都会重新计算)。

于 2009-02-03T06:36:08.313 回答
7

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

我得出的结论是,您几乎应该始终使用代理键。如果您使用自然键,这些可能会更改并且更新主键/外键通常不是一个好主意。

于 2009-02-03T06:31:46.920 回答
4

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

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

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

于 2009-02-03T06:22:35.237 回答
3

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

  • 考虑为 Type 创建一个单独的表,比如列 Id 和 Desc,然后在该表中创建一个外键 TypeId。更进一步,以使事物正常化。但这可能并不理想。如果你认为它有某种目的就去做

  • 如果以后你们考虑转向 UUID,将其设为 String 确实有意义。您不需要更改数据类型

[已编辑]

我同意 Cletus 的观点。事实证明,该代理键在某些现实生活项目中是有益的。它们允许变化,你很清楚,变化是唯一不变的。

于 2009-02-03T06:32:14.937 回答
3

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

于 2009-12-17T16:34:09.200 回答
2

我个人认为第一种方法要好得多。它让数据库软件做简单的整数比较来查找和排序,这将提高表操作性能(SELECTs、complex JOINs、by-key INDEX lookups等)

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

于 2009-02-03T06:22:47.997 回答
1

由于您提到的原因,我更喜欢示例 1,我能想到的使用示例 2 的唯一论点是,如果您尝试从现有数据库中容纳字符串 ID(很常见),但即使在这种情况下,我也更喜欢使用以下方法。

==AssetId(PK)==Type========DeprecatedId====
  12345        "Manhole"   "MH64247"
  155415       "Pit"       "P6487246"
于 2009-02-03T07:46:39.793 回答
0

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

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

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

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

于 2009-02-03T06:31:50.290 回答
0

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

(您也可以通过使用全局序列来生成数字键,或使用不同的数字范围、最后一位数字或其他方式来获得此优势。这样您就没有性能劣势,但也许您不会那么容易找到该表。 )

于 2009-12-17T16:30:04.263 回答