如果我们使用自动递增的标识列和 PK,则违反 3NF

Posted

技术标签:

【中文标题】如果我们使用自动递增的标识列和 PK,则违反 3NF【英文标题】:Violation of 3NF if we use an auto-incremented identity column along with a PK 【发布时间】:2018-07-23 01:56:16 【问题描述】:

正如 Thomas Connolly 和 Carolyn Begg 撰写的 Database Solutions Second Edition 书第 180 页所述:

第三范式 (3NF) 已经在 1NF 和 2NF 中的表,并且在 可以从中计算出所有非主键列中的值 只有主键列,没有其他列。

我见过很多情况,人们使用标识列,尽管他们的表中已经有一个主键列。记录也可以从标识列中计算出来,那么如果我们在表中使用自增标识列和主键,是否违反了 3NF?

更新:如果不是这样,哪个列应该被引用为另一个表中的外键。主键列还是标识列?

【问题讨论】:

PK 不重要,CK 重要。此外,重要的不是“非 PK”列,而是“非素数”,即“非 CK”。其余的“定义”也太草率了,没用。自动增量无关紧要。阅读其他一些教科书。数十个在线免费的 pdf 格式。另请注意,在 SQL 中,PK 声明意味着 UNIQUE NOT NULL,即超级键,不一定是关系/实际 PK。 请通过发布新问题提出新问题。但是找出关系 FK 是什么以及 SQL FK 是什么。后者是一个列集,当子行值不包含空值时,其子行值必须作为 SQL PK 或 UNIQUE NOT NULL 出现在其他地方。声明任何尚未通过其他 FK 声明传递执行的 FK。同样,您需要学习正确的定义。然后应用它们。不要担心定义中没有的事情。 外键可以引用任何候选键。关系模型没有说明哪个候选键是外键引用的“更好”目标。如果您使用框架或 ORM 来构建软件,它可能会坚持引用标识列。 【参考方案1】:

没有。 3NF 定义的“官方”措辞通常使用术语“主要属性”或“非主要属性”。如果你的书暗示这意味着“主键的属性”,那么把你的书扔进垃圾箱。这是错误的。 “主属性”是指“属于 ANY 键的一部分的属性”,“非主属性”是指“不属于 ANY 键的属性” .因此,在关系模式中引入您的“自动增量属性”(以及所有使其成为键的适用 FD)不可能引入 3NF 违规,因为它不会引入非主属性。

【讨论】:

那么我应该在另一个表中使用哪一列作为外键?主键列还是标识列? @ElhamKohestani 忘记约束并了解如何选择捕获您的业务/应用程序状态的表含义。你的(可怜的) texbook 有副标题“一步一步的方法 [...]”。它说什么?【参考方案2】:

您引用的段落是错误的 - 或者至少它是如此非正式,以至于无法解释。

如果关系 R 处于第二范式,则关系 R 处于第三范式 并且 R 的每个非主属性都非传递依赖于 R的每个候选键。

Codd E. F.,“数据库关系模型的进一步规范化”

候选键很重要。一张有多个键的表没有错。

【讨论】:

【参考方案3】:

那本书《数据库解决方案:构建数据库的分步指南》(2004 年第 2 版)一团糟。不幸的是,它说错了话,误导了他们,而且他们的很多措辞都非常糟糕——比如“锻炼”——这是非正式的,从未定义过。

第三范式 (3NF) 已经在 1NF 和 2NF 中的表,其中所有非主键列中的值只能从主键列而不是其他列中计算出来。

这个错误的定义实际上是非正式的,当一个表只有一个 CK(候选键)时。但是这本书并没有除了间接后来当它给出了另一个涉及PK的错误定义(主要键):

第三范式 (3NF) 的正式定义是第一个表 和第二范式,其中没有非主键列是可传递的 依赖于主键。

后来它仍然说可以有多个 CK,但它仍然给出了错误的定义:

因此,对于具有多个候选键的表,您可以使用广义 3NF 的定义,它是一个在 1NF 和 2NF 中的表,并且在 可以从中计算出所有非主键列中的值 只有候选键列,没有其他列。

错误地说“主键列”,其中 主列CK 列 是正确的。

他们的另一本书 Database Systems 4th Edition 2005 还介绍了当只有一个 CK 时的特殊定义情况,但稍后给出“一般”定义。至少那些“主要属性”是正确的。

第三范式 (3NF) 的一般定义 是在第一范式和第二范式中的关系 其中没有非候选键属性传递依赖于任何候选键。

在任何正常形式的表中都有多个 CK 并没有什么不寻常的地方。

【讨论】:

根据***.com/questions/377375/…这个问题的答案@我想看这些书系列。你有什么比这本书更有效的建议?我有这个系列的最新一本书(第六版)。您建议我应该阅读它还是使用其他教科书? 哪本书? DD59 答案中的第二本书现在是我的答案中糟糕的“数据库系统”的第 6 版,作者与您的问题中更糟糕的“数据库解决方案”相同。我刚刚在第 6 节中读到的第一件事是“如果 A 和 B 是关系 R 的属性,则 B 在功能上依赖于 A(表示为 A -> B),如果 A 的每个值都关联仅具有 B 的一个值。(A 和 B 可能各自包含一个或多个属性。)"--它们自相矛盾--A 和 B 是属性,然后它们是 集合 i> 的属性。同样扭曲的文字。相同的规范化表示在很多方面都很糟糕。 DD59 的另一本书(第 3 版)也充满了规范化的误解和草率。 I suggest 每个人都阅读日期重新规范化、Darwen 上的关系数据库(关系和查询)(和基本 SQL)和 Halpin 重新信息建模。 (ORM2 和相关方法主要导致 5NF 设计。)但这些只是数据库系统问题的一部分。我在网上找到了大约 2 打免费的教科书。我对它们都不熟悉,并且重新规范化还不能将特定的推荐为真正

以上是关于如果我们使用自动递增的标识列和 PK,则违反 3NF的主要内容,如果未能解决你的问题,请参考以下文章

在oracle sql中违反了PK

从零开始自动递增 PK - EF Core 代码优先

带有标识(自动增量)列的 BULK INSERT

从 MySQL 中的现有表生成更改日志时,liquibase 如何处理自动递增的 PK?

如何使用 sql developer 设置自动递增列

在oracle 怎样设置自动递增的的字段,也就是设置自动递增的ID 主键