当我可以使用其他人作为关键字段时,为什么要创建 ID 列?

Uğu*_*han 54 mysql sql-server primary-key uniqueidentifier surrogate-key

可能的重复:
为什么使用 int 作为查找表的主键?

到目前为止,我习惯于为每个表创建一个 ID 列,它的实用性使我不必考虑有关主键理论的决策。

我大学的教授建议全班从一个或多个字段制作主键,这些字段构成关于每一列的一个唯一信息。是的,我想养成使用自然键而不是代理键的习惯。维基百科上列出了代理键的优缺点,我严格推荐这篇文章

我见过人们对所有内容都使用整数 ID 字段,但没有人评判这种方法,因为

  • 它“看起来”高效
  • 使用了一个数字字段,它看起来更酷,因为它在内存中每行的大小

我开始认为额外的 ID 字段只是创建冗余数据而没有实际好处。那么当我可以使用其他列作为关键字段时,为什么还要创建 ID 列呢?

  • 如果您的 ID 字段是 32 位,则它已经相当于 4 个 ASCII 字符。
  • 如果您的 Id 字段是64 位整数,则它是8 个字符的字符串,因此它实际上并没有节省那么多内存(这里暗示的是用于比较的内存。额外的 id 列已经添加到使用的内存中(HDD 和 RAM) ) )
  • 额外的 ID 字段会使您的索引成本加倍,因为您还将索引一个可以用作主键的唯一字段。
  • 如果您需要可以用作关键字段的数据,则进行额外的联接,例如,如果您在一篇博客文章中存储了唯一的用户 ID,以显示作者姓名,则进行联接查询,如果您的密钥字段是作者的名字,你不需要加入,因为你将相关数据存储在博客帖子表中。具有有意义数据的外键字段减少了子查询或连接的需要

在此处输入图片说明

  • 创建一个额外的 id 字段“添加”到内存负载,它不是唯一字符串字段的替换,您不是用整数替换 char-varchar 字段,而是添加一个额外的列并创建额外的数据流。所以任何数据存储的比较都应该在“string”和“int+string”之间进行。添加整数 id 字段不节省空间。

另一方面

  • 分配从用户输入中获取价值的主键数据可能会出现问题,因为人们可能会输入错误的社会安全号码,并且由于独特的政策,想要注册的实际人员将无法注册。这可以通过在原始号码上添加一个或多个额外数字来规避。

额外资源:

  1. 自然vc代理键的比较

我从阅读文章中得出的结论是,我应该尽可能使用自然键,而不是每次都跳过考虑自然键并使用代理键,好像这是一个标准。

JNK*_*JNK 46

1 -它更快。JOIN上的整数比快得多JOIN上字段的字符串字段或组合。比较整数比比较字符串更有效。

2 -它更简单。 与基于不同数据类型的其他字段的组合相比,基于单个数字字段映射关系要容易得多。

3 -它与数据无关。 如果您匹配,则ID无需担心关系会发生变化。如果你匹配一个名字,如果他们的名字发生变化(即结婚),你会怎么做?如果你匹配一个地址,如果有人搬家怎么办?

4 -效率更高 如果您在(自动递增)int 字段上进行集群,则可以减少碎片并减少数据集的整体大小。这也简化了覆盖关系所需的索引。

编辑

对于您刚刚添加的具体要点:

1 和 2 - 比较 int 仍然比字符串快得多,空间考虑除外。您还可以方便地忽略存储可变长度字段长度(通常每行每字段 2 个字节)所需的开销。

3 - 如果你在ID场上聚集,那么它不会增加任何额外的东西。它节省了空间,因为您使用的是更有效的行 ID。

4 - 然后当那个人更改他们的用户名时,您的链接都会中断。

5 - 你真的不知道你在说什么。您确实必须存储数据,这是正确的,但是JOIN在 int 上进行索引和在 int 上比在其他字段的组合上更有效。

  • “它与数据无关” 作为前端开发人员,这对我来说是最重要的。如果数据曾经在前端应用程序中使用过——尤其是在积极开发中的应用程序——这可以节省大量的开发时间。id 将始终是 URL 安全的、不区分大小写的,并且不需要额外的逻辑。这可以在服务层通过一个好的 API 来解决,但实际上它经常变成前端开发人员编写大量不应该存在于前端的代码。在项目的上下文中,任何比 id 字段更复杂的东西都会带来惊人的工作量。 (2认同)

Mic*_*ant 21

因为人们从经验中了解到,使用这些字段会导致问题。

我已经开发了 20 年的数据库应用程序。最关键的是,我花了五年时间在数据仓库上工作。在早期,选择另一个领域似乎没问题。然后我们发现重复的记录,有时缺少唯一的验证,有时(经常)用户提供了现在需要合并的不同信息,或者其他什么,合并和管理记录是一场噩梦。

即使(或什至特别!)当标识符“看起来”是唯一的时,这也可能不是真的。例如:美国社会安全号码。对一个人来说应该是独一无二的吧?当然,但是如果过去用户输入错误的 SSN 记录输入了一些记录怎么办?现在,为新记录输入的新有效数字可能会出现冲突问题。附带说明是,主键也不应该显示,因为它们会导致用户对它们的假设,而且它们也不适合网站 URL 的最佳安全模型。
始终考虑 - 用户是否将这个 URL 加入书签并期望它在未来工作?

所以人们已经学会了:

当代理具有“任何”业务价值或意义时,不要使用“代理键”(例如 SSN)作为主键。
相反,使用唯一且不是从应用程序数据派生的主键。


小智 12

如果您想查找数据,您确实希望基于一个或多个整数字段来执行此操作。这就是为什么许多人为此使用 ID 字段的原因。

但是,如果您有一张用于多对多关系的表,则实际上并不需要它。假设您有以下两个表:

表news id integer title varchar item text

表标签 id 整数名称 varchar

对于新闻中的每一项,您都希望添加一个或多个标签,因此您创建了以下表格:

表 news_tags news_id 整数 tags_id 整数

在这种情况下,实际上不需要创建额外的 id 列,因为您根本不需要它。


小智 -1

因为ID是用来识别一切的。以用户为例 - 通过用户名搜索用户比通过整数(ID)搜索用户慢