举例说明2NF与3NF


13

我对第二范式(2NF)有疑问,但无法使用Google来解决。这让我发疯,因为我是一名老师,而且我不想向学生们教错误的东西。

让我们有一个包含5个字段的表格。

评分= {学生姓名,学科编号,学科名称,#考试,年级}

依赖性是这样的:

学生姓名,科目代码,#考试->年级

SubjectCode-> SubjectName

SubjectName-> SubjectCode

因此,候选键1是{StudentName,SubjectCode,#Exam},候选键2是{StudentName,SubjectName,#Exam}

主要属性是{StudentName,SubjectCode,SubjectName,#Exam},非主要属性是Grade

根据第二范式的定义,非素数属性不能取决于候选密钥的一部分。唯一的非素数属性(Grade)不依赖于候选键的一部分,因此该表看起来像2NF。

问题是我认为有些不对(我可能错了)。我认为受试者应该有自己的桌子。

评分= {学生姓名,学科代码,#考试,年级}

主题= {主题代码,主题名称}

但是2NF不会产生这种情况。3NF与非素数属性之间的依赖关系有关,因此也不会产生这种情况。但是在我看来,这是正确的结果,因为它没有冗余。

我想如果非素数属性定义为“不是候选键的属性”,则2NF将产生所需的结果。但是我已经一遍又一遍地检查了这一点,并且非素数属性被定义为“对候选键不信任的属性”。

我究竟做错了什么?

Answers:


9

您的关系是3NF(不仅是2NF),因为正如您所说,唯一的非主要属性是Grade,它仅显示在FD 的右侧。

该关系不在BCNF中,因为两个小FD的左侧不是超键。

但是,您可以无损地分解与(SubjectCodeSubjectName)和(StudentName,SubjectCode,#Exam,Grade)或(StudentName,SubjectName,#Exam,Grade)的关系

此分解为您提供了两个BCNF关系,并保留了所有功能依赖性。这并非总是可能的(您可以始终分解与3NF的关系,但不一定分解为BCNF的关系)。

2NF

如果要使用2NF(而不是3NF)的示例,则您的关系需要包含传递依赖。

例如,假设您有一个“分数”列。直观地讲分数->成绩,因为所有具有相同分数的考试都应获得相同的成绩(否则会很不公平),但请注意,由于多个分数可以具有相同的成绩(11%和12%,所以我们不能说成绩->分数)例如,很可能是“失败”)。

现在您的关系是:

评分学生名,科目代码,科目名称,#考试,分数,年级

并且您有了一种新的冗余形式,因为每次您输入的结果与另一个“评分”记录的得分相同时,您还必须重复相应的成绩。为了达到3NF,您可以分解为

分数分数分数,分数

得分为关键,并且

分数(StudentName,SubjectCode,SubjectName,#Exam,Score


4

你说的一切都是对的。主题代码,SubjectName需要进入自己的表中,以实施所需的依赖关系。这是为什么2NF和3NF不足以产生好的数据库设计的一个很好的例子-您需要Boyce Codd范式(BCNF)。

2NF和3NF被BCNF取代,从实际上讲,这些较小的NF已过时*。BCNF是更重要的并且可以说更容易解释和应用。作为老师,我建议您花更多的时间在BCNF上,而花在2NF和3NF上的时间更少。如果表格满足BCNF的要求,那么它也同时满足2NF和3NF。


* 3NF不是保留最高依赖项的范式。基本密钥范式(EKNF)是。严格说来,使3NF过时的是EKNF,而不是BCNF,但是EKNF被无理地忽视了,大多数教科书和课程甚至都没有提到它。等同于相同的事情是针对BCNF设计,然后检查所有所需的依赖关系和任何其他完整性规则是否可以正确实施-如果不正确,则修改设计。没有一个NF是解决数据完整性的完整解决方案,但是BCNF通常最接近,并且最容易解释和使用。


您是否对EKNF有很好的参考,特别是对于初学者?我正在尝试阅读它,并发现很难找到有效的文档。在Wiki的单行摘要之外,我还没有遇到关于EKNF和BCNF / 3NF的细微差别的有效功能说明。
Saijin_Naib

2

我不会说自从我第一次学习所有这些以来已经有多长时间了。但是我确实记得我有一个教授,他忠实地教了我们“函数依赖”和“非素数属性”以及所有其他流行词的正确含义后,给我们提出了一系列简单的问题,以询问是否有一个特定的正常表格已到达。让我们看看我是否还记得很久...

我们已经确定了候选键,因此我们会问剩余的非素数属性这个问题。在这种情况下,只有一个:年级。

我们唯一识别等级所需的绝对最低限度信息是什么?我们需要知道学生,科目和考试内容。很好,这是候选键之一。

编辑: VVV

但是答案也可能是学生姓名,学科名称和考试。这将匹配第二个候选密钥。

假设SubjectCode和SubjectName都是Subject实体的候选键,则没有理由在此处同时使用这两个字段。一个对Subjects表中一行的唯一引用就足够了。因此,我们可以安全地完全删除SubjectName字段,而无需牺牲模型的任何完整性。

但是,在我最初的回答中,由于希望显示出另一种规格化,我忽略了SubjectName已在候选关键字中使用,而将其视为另一个非素数属性。我想对我来说是如此明显,以至于这是一个无用的领域,我认为这对每个人都一样明显,并且既然我们摆脱了该领域,那有什么关系呢?

但是,除了删除答案的那一部分之外,我将其保留下来进行比较。

结束编辑: ^ ^ ^

我们唯一标识主题名称所需的绝对最低限度的信息是什么?

SubjectName仅取决于SubjectCode-候选键的子集。因此,该元组不在2nf中。SubjectCode应该是Subjects表的主键,因此是放置SubjectName的正确位置。从该元组中删除它,现在它位于2nf中。

如果我们问一个属性问题,而答案不是全部或部分候选键,则该元组不在3nf中。但是这个元组在3nf及更高版本中也很普通,因为我们已经用完了很多问题。;)

注意:当我们说“规范化”时,我们指的是应用于逻辑实体的过程。由于提供的元组似乎是一个称为“等级”的实体的定义,因此我们可以对其进行规范化。但是,我曾经说过“该元组不在2nf中,”更恰当的说法应该是“该实体不在2nf中”。如果造成混乱,我深表歉意。


2

唯一的非素数属性(Grade)不依赖于候选键的一部分,因此该表看起来像2NF。

它在2NF中。

问题是我认为有些不对(我可能错了)。我认为受试者应该有自己的桌子。

没有理由期望受试者应该有自己的表格将原始表格分解为2NF。您将某种模糊的“应该”概念与任何特定范式实际上给您的东西混淆了。

3NF与非素数属性之间的依赖关系有关,因此也不会产生这种情况。

“ 3NF与非主要属性之间的依赖性有关”不是对3NF的正确定义,因此“因此也不会产生这种现象”不是一个合理的结论。尽管应用实际定义确实表明该表采用3NF格式,但不需要学生表。但是同样,没有理由期望会有这种情况。

但是在我看来,这是正确的结果,因为它没有冗余。

同样,“冗余”是无助的模糊,因此您的“因为”和学生餐桌的期望是不正确的。不同的范式没有特定类型的异常和相关的“冗余” ,并受其影响。但是,归一化未解决的其他“冗余”可以保留。

该表不在BCNF中,因为它具有不超出CK的FD。根据BCNF对其进行分解将导致具有学生表。BCNF是处理FD附带的JD(联接依赖项)的最高标准形式。但是,其他JD可能有问题(即“未由CK暗示”),应通过标准化为5NF来删除。

PS原始表还满足FD {学生名,主题名,#考试}->成绩。

依赖性是这样的:

这是什么意思?这还不清楚。

您的意思是,“所有这些非平凡的FD都成立了”吗?不,因为它们暗示着第四。“这里有一些FD持有”?不,这意味着传递闭包中的FD成立,但并不表示其他FD 成立,但您可以确定CK。“持有的FD恰好是这些的传递闭包中的FD”?如果您这样想的话,那么您只有在显示了它之后才能知道它,也就是说,您必须找到那个闭合(通常通过最小/规范的覆盖),然后表明没有其他FD。你是否?无论如何,您写的内容并不意味着那。因此,我希望您不会对FD&CK的情况做出合理的推理。


0

您是正确的,主题需要使用自己的表格。如果您选择一个候选密钥,则subject_code或者subject_name成为非主候选密钥。然后,从成绩表中删除非主要科目字段。

您对主题有功能上的依赖性,为此您有两个唯一的标识符。subject_code和之间的传递依赖关系证明了这一点subject_name。这表明需要创建一个包含这两个字段的表,并从所有其他表中删除这些字段之一。该表很可能具有其他依赖列,尽管在此示例中我看不到。您已经选择了第三标准格式。

等级取决于新等级表中的其他三个字段(候选关键字)。如上所述,您需要为主题表选择一个候选字段。通常,如果可用,这将是一个代码值,因为它们趋于更稳定。结果模型为3nf,因为所有非关键字段都完全依赖于主键中的字段。

对问题的进一步分析(要求)可能会产生一个会话表,并对其施加标记。当前的模式不太可能涵盖重复课程的学生。这将在以后的课程中介绍。

学生也有可能成为单独的表格,因为可能有多个同名学生。可以通过添加合成主键(学生编号?)来解决。

subjects --->  sessions ---+--> grades
students  -----------------+

3
“如果您选择一个候选键,subject_code或subject_name都将成为非主要候选键。” 这是完全错误的。其余的分析有一些有价值的要点,但是当一个错误的论点开始时,我们不能依靠这些结论。
ypercubeᵀᴹ

-7

我正准备删除它,因为它被认为是不正确的

主题名称也是非主属性,它取决于主键主题代码的一部分(中断规则-主列上的任何列都不得有任何部分依赖)。

这在第二范式中是被禁止的,因此应根据您的怀疑将其放在自己的桌子上。

我认为您不了解的地方是识别两组候选键,在创建表时,您必须选择一组候选键作为主键。其余的列将成为非主要属性,即,如果您选择了第二个候选键,则主题代码将成为非主要属性,具体取决于主键的一部分(主题名称),并应放置在其自己的表中。

重要的是要教第一,第二和第三范式相互依存。BCNF本质上也是对第三范式的扩展,因此必须牢牢掌握较低的层次。

进一步; 有经验的开发人员不会考虑标准化的独立级别,因为许多规则变得直观。

他们还将知道何时打破规范化规则来解决某些设计和优化问题。规范化应该被视为指导良好设计的准则,而不是严格的规则,我认为这也将是一个很好的教学重点。


1
OP正确地说“候选键2为{StudentName, SubjectName, #Exam}。”因此StudentName是主要属性。
ypercubeᵀᴹ

1
“在创建表时,必须选择一组候选键来构成主键。其余的列将成为非主键属性。这显然是错误的。
ypercubeᵀᴹ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.