Boh*_*ian 8 database-design relational-theory
据我了解,第三范式(3NF)基本上意味着应该只有一个键。
如果带有自动增量id
列的表也有一个已知的唯一且不为空的列,例如社会保险号,则此另一列可用作键。
忽略实际/业务问题(例如,在将 SSN 作为密钥/FK 传递时的安全性/隐私风险),从严格的模式设计方面来看,这样的表是否不会在 3NF 中,因为实际上有 2 个密钥?
答案是否会因另一列上是否有唯一键而有所不同?如果是这样,为什么?
如果 R 的每个非主要属性都非传递地依赖于 R 的每个候选键,则关系 R 是第三范式
EFCodd,1971 年,数据库关系模型的进一步规范化
在关系的定义中,关系必须至少有一个键是隐含的。3NF 或任何其他范式都没有要求关系应该只有一个键。
不幸的是,关于数据库设计和规范化的书籍有很多关于只有一个键的关系的例子,而有多个键的例子却很少。鉴于如今多个键似乎是非常普遍的做法,这让我感到很奇怪。非学术文献中实际例子的缺乏似乎是导致数据库设计中键的作用产生混淆的原因之一。另一个引起混淆的原因是流行的助记符“只有钥匙”。这句话通常归因于比尔肯特,但它不是 3NF 的准确定义。
据我了解,第三范式(3NF)基本上意味着应该只有一个键。
2NF、3NF 和 Boyce Codd 范式 (BCNF) 处理函数依赖性。2NF 中的表意味着不存在部分键依赖关系,其中非键列依赖于多列键的某个真子集。像我们示例中的表这样的表已经处于 2NF 中,因为每个候选键都是一列。3NF 中的表意味着每个非键列在功能上也不依赖于其他非键列,从而创建传递依赖。有一个或一百个候选键并不重要。实际上它是 BCNF,而不是 3NF,它是函数依赖关系的“最终”范式。这是因为表可以是 3NF,但不能是 BCNF,因为可能有多个重叠的候选键。因此,当我们使用术语3NF来表示函数依赖性的“完全规范化”时,我们真正的意思是 BCNF。
如果一个带有自动增量 id 列的表也有一个已知唯一且不为空的列(例如社会安全号码),则可以使用该其他列作为键。
不仅可以,而且如果我们想确保数据库中存储的数据与我们在现实世界中确定的规则保持一致,就必须如此!
忽略实际/业务问题(例如,将 SSN 作为密钥/FK 传递时的安全/隐私风险),从严格的模式设计方面来看,这样的表不会在 3NF 中,因为实际上有 2 个密钥?
如上所述,表是否属于 3NF(或更重要的是 BCNF)与其包含的候选键数量正交。
答案是否会因另一列上是否有唯一键而有所不同?如果是这样,为什么?
不,只是因为确定表是否属于 3NF 与它有多少候选键无关。相反,它与确保所有非键列在功能上完全依赖于这些候选键有关。
但这确实提出了一个有趣的观点。请注意,在 DBMS 中定义为约束的唯一键与在概念业务模型中定义为业务规则的唯一标识符不同。也许在我们的世界中,我们总是知道这个人的 SSN,因此它可以作为一个人的候选键,也许我们还在逻辑模式中引入一个代理键,我们称之为Person Id。我们的商业模式包括这样的规则:SSN 是一个人在我们的世界中的唯一标识符。这意味着所有描述性属性在此身份属性上的功能依赖性。该规则不会仅仅因为我们忘记或选择不通知 DBMS 而改变。这正是声明约束至关重要的原因- 这样 DBMS 才能确保存储的数据与业务模型的规则一致!如果我们没有对 SSN 创建唯一约束,我们现在可能会无意中为具有相同 SSN 的同一个人创建多行;每行都有不同的 Person Id!
关于这些主题的优秀入门读物是 Fabian Pascal 的《实用数据库基础系列》和 Chris Date 的《数据库设计和关系理论》,这个答案就是从中得出的。虽然 Fabian 的每篇论文都是必读的,但论文#1(明确定义了概念、逻辑和物理级别之间的差异)和论文#4(明确定义了各种键)专门解决了这个问题。同样,克里斯的整本书都是必读的,而第二部分是专门讨论函数依赖性规范化的部分。