我无法向一个五岁的孩子解释这些东西。我试过了。但我也许可以对这个主题有所了解。您需要知道的第一件事是多年来对 1NF 有多种定义,这些定义有时会相互冲突。这很可能是您困惑的根源,或者至少是其中的一部分。
一个有用的信息是 Ed Codd 在第一次定义它时的目的是什么。 Ed Codd 早在 1970 年发表的论文中就定义了第一范式,他称之为范式。他在那篇论文中的目的是证明按照关系线构建的数据库将具有现有数据库所具有的所有表达能力。现有的数据库通常处理拥有一组孩子的父母。例如,如果父数据项包含有关学生的数据,则每个孩子可能包含有关学生正在学习的一门课程的数据。
您实际上可以根据数学关系定义这样的结构,方法是允许关系的一个属性本身就是一个关系。我将称之为“嵌套”关系,虽然我不记得 Ed Codd 是怎么称呼它的。在定义与数学关系密切相关的关系数据模型时,Ed Codd 出于各种原因想要禁止这种结构。他的理由大多是实际的,让构建第一个关系数据库更加可行。
因此,他用他的一些论文来证明您可以将属性限制为“简单”值,而不会降低关系数据模型的表达能力。我将暂时回避“简单”的含义,尽管值得回到。他称这种限制为“正常形式”。一旦发现了第二个范式,范式就被重命名为第一个范式。
当需要构建关系数据库时,工程师决定采用一种称为“表”的数据结构。 (我不知道实际的历史,但这是近似的)。表是由行和列组成的逻辑结构。它可以被认为是一个记录数组,其中每条记录代表一行,并且所有记录都有相同的标题。
现在,如果您想要这样的结构来表示关系,您必须加入一个限制,以防止两行具有完全相同的值。如果你有这样的重复,这将不代表一个关系。根据定义,关系具有不同的元素。这就是主键的用武之地。具有主键的表不能有重复的行,因为它不能有重复的键。
但我还没有完成。你没有问这个,但它已经在堆栈溢出中出现了一千次,所以值得放在这里。设计人员可以通过创建一个包含文本的列来打破 Ed Codd 的初衷,而该文本又包含逗号分隔的值。在 Codd 的原始公式中,值列表并不“简单”。
这对新手来说非常有吸引力,因为它看起来更简单、更有效,存储一个逗号分隔值的表比创建两个表一个用于父记录,另一个用于子记录,并在它们都是时加入它们需要一个查询。连接对于新手来说并不简单,而且它们确实需要一些计算机资源。
几乎在所有情况下,列设计中的 CSV 都是一种不幸的设计。原因是某些本来可以通过索引快速完成的查询现在需要全表扫描。这可以将几秒钟变成几分钟或几分钟变成几小时。比加盟贵很多。
因此,您必须教新手为什么使用密钥访问所有数据是一件好事,这意味着您必须教他们 1NF 的真正含义。这就像教一个五岁的孩子一样难。新手通常不像五岁的孩子那么无知,但他们往往更固执。