SQL 表中的 ID 字段:规则还是法律?

Posted

技术标签:

【中文标题】SQL 表中的 ID 字段:规则还是法律?【英文标题】:ID fields in SQL tables: rule or law? 【发布时间】:2009-01-13 15:55:22 【问题描述】:

只是一个快速的数据库设计问题:您总是在每个表中使用 ID 字段,还是只在大多数表中使用?很明显,您的大多数表格都会受益,但是否有您可能不想使用 ID 字段的表格?

例如,我想添加向另一个表 (foo) 中的对象添加标签的功能。所以我有一个表 FooTag,其中有一个 varchar 字段来保存标签,还有一个 fooID 字段来引用 foo 中的行。我真的需要围绕一个基本上任意的 ID 字段创建一个聚集索引吗?使用 fooID 和我的文本字段作为聚集索引不是更有效吗,因为无论如何我几乎总是会通过 fooID 进行搜索?另外,在聚集索引中使用我的文本将使数据保持排序,从而在我必须查询数据时使排序更容易。缺点是插入会花费更长的时间,但这不会被选择期间的收益所抵消,而这会更频繁地发生吗?

您对 ID 字段有何看法?可弯曲的规则,还是牢不可破的法律?

编辑:我知道提供的示例未标准化。如果标记是项目的主要部分,标记多个表和其他“附加”,那么两个表的解决方案将是一个明确的答案。然而,在这个最简单的情况下,标准化是否值得?它会节省一些空间,但在运行查询时需要额外的连接

【问题讨论】:

【参考方案1】:

在大部分编程中:规则,而不是法律

例外证明:一些两列表的存在只是为了在其他更有意义的表之间形成关系。

【讨论】:

【参考方案2】:

如果您要制作在两个或多个其他表之间桥接的表,并且您需要的唯一字段是双 PK/FK,那么我不知道您为什么还需要其中的 ID 列。

ID 列通常会很有帮助,但这并不意味着您应该在每个场合都使用它们。

【讨论】:

【参考方案3】:

正如其他人所说,这是一般规则,而不是绝对规则,并且有很多例外(例如具有复合键的表)。

在一些偶然但有用的情况下,您可能希望在已经具有(通常是复合的)唯一标识符的表中创建人工 ID。例如,在一个系统中,我创建了一个表格来存储零件编号;尽管零件编号是唯一的,但它们实际上可能会发生变化——我们添加一个任意整数 PartID。不是很常见,但它是一个典型的真实示例。

【讨论】:

【参考方案4】:

一般来说,您真正想要的是能够在可能的情况下使用某种方式来唯一标识一条记录。它可以是一个 id 字段,也可以是一个唯一索引(不必只在一个字段上)。任何时候我以为我可以在不创建唯一标识记录的方法的情况下逃脱,但事实证明我错了。但是,所有表都没有自然键,如果没有,您确实需要某种 id 文件。如果你有一个自然键,你可以使用它,但我发现即使这样,在大多数情况下我也需要一个 id 字段,以防止在自然键更改时进行过多更新(它似乎总是在更改)。再加上使用了数百个涉及许多不同主题的数据库,我可以告诉你真正的自然键是罕见的。正如其他人提到的那样,表中不需要一个 id 字段,它只是用来连接两个具有多对多关系的表,但即使这样也应该有一个唯一的索引。

【讨论】:

【参考方案5】:

如果您需要从该表中检索具有唯一 ID 的记录,那么可以。如果您将通过由外键组成的其他组合键来检索它们,那么不会。您最不需要的是不使用的字段、数据和索引。

【讨论】:

【参考方案6】:

聚集索引也不需要位于主键或代理项(标识列)上。

但是,您的设计并未标准化。通常对于标记,我使用两个表,一个标签表(带有代理键)和一个从标签到主题表的链接表,使用标签表中的代理键和主题表中的主键。这允许您的标签应用于不同的实体(照片、文章、员工、位置、产品等)。它允许您对多个表强制执行外键关系,还允许您发明标签层次结构和有关标签表的其他内容。

就本设计中的索引而言,它将由使用模式决定。

【讨论】:

【参考方案7】:

一般来说,开发人员喜欢在除了“链接”表之外的所有表上都有一个 ID 字段,因为它使开发变得更加容易,我也不例外。另一方面,DBA 认为自然主键由 3 或 4 列组成没有问题。尝试并获得良好的数据库设计可能会令人费解。

【讨论】:

以上是关于SQL 表中的 ID 字段:规则还是法律?的主要内容,如果未能解决你的问题,请参考以下文章

mysql 设置外键,能否将表中多个字段关联到另一个表中的同一字段

怎么用SQL语句同步两个表中的字段值?

SQL中如何根据字段名查找该字段名存在于数据库的哪些表中?

用SQL怎样根据一个表种的字段ID查出另一个表中的数据?

sql 删除表中的字段的最后一个字符

SQL -- 基本书写规则