我刚刚阅读了@ PerformanceDBA的论点:6NF和EAV.我很好奇.我以前一直对6NF持怀疑态度,因为它只是"仅仅"在表格上粘贴了一些时间戳列.
我一直使用数据字典,不需要被说服使用它,或生成SQL代码.所以我希望答案需要一个用于生成代码的字典(或目录).
所以我想知道6NF如何处理一个非常简单的例子.项目,描述和价格表.价格随时间而变化.
那么无论如何,在转换为6NF时,Items表是什么样的?什么是"桌子爆炸?" 发生在这里?
如果该示例不适用于表格这么简单,请随意添加必要的内容以获得重点.
Per*_*DBA 41
我实际上开始把答案放在一起,但我遇到了并发症,因为你(很容易理解)想要一个简单的例子.问题是多方面的.
首先,我不了解你的关系数据库和5NF的实际专业水平; 我没有起点,然后讨论6NF的具体细节,
其次,就像任何其他NF一样,它是杂色的.你可以勉强进入它; 你可以为certan表实现6NF; 你可以在每张桌子上吃饱,等等.当然桌子爆炸了,但是你将它归一化,然后杀死爆炸; 这是6NF的高级或成熟实现.当您要求最简单,最直接的示例时,无法提供全部或部分6NF级别.
我相信你明白一些表可以"在5NF",而其他表是"在6NF".
所以我把它们放在一起给你.但即使这需要解释.
现在SQL几乎不支持5NF,它根本不支持6NF(我认为dportas用不同的词语说同样的事情).现在我在深层实现6NF,出于性能原因,简化了旋转(整个表格;任何和所有列,而不是MS中的愚蠢PIVOT功能),柱状访问等.为此你需要一个完整的目录,这是一个扩展到SQL目录,支持SQL不支持的6NF,并维护数据完整性和业务规则.所以,你真的不想实现6NF的乐趣,你只有在需要时才这样做,因为你必须实现一个目录.(这就是EAV人群不会做的事情,这就是大多数EAV系统存在数据完整性问题的原因.他们中的大多数都没有使用SQL确实具有的声明性参考和数据完整性.)
但是大多数实施6NF的人都没有实现更深层次的完整目录.它们具有更简单的需求,因此实现了更浅的6NF水平.所以,让我们来看看,为您提供一个简单的例子.让我们从一个声明为5NF的普通Product表开始(让我们不要争论5NF是什么).该公司销售各种不同类型的产品,一半是强制性的,另一半是可选的,这意味着,根据产品类型,某些列可能是空的.虽然他们可能在数据库方面做得很好,但Null现在是一个大问题:对于某些ProductTypes而言应该是Null的列是Null,因为声明声明为NULL,并且他们的应用程序代码仅与下一个人的代码一样好.
因此他们决定使用6NF来解决这个问题,因为6NF的副标题表明它消除了Null问题.第六范式是不可简化的范式,此后不再有NF,因为数据不能进一步标准化.行已经标准化到最大程度.6NF的定义是:
当行包含主键,并且最多包含一个属性时,表在6NF中.
请注意,根据该定义,全球数百万个表已经在6NF,而没有这个意图.例如.典型的参考或查找表,只有PK和描述.
对.好吧,我们的朋友看看他们的Product表,它有八个非关键属性,所以如果他们生成产品表6NF,他们将有八个子产品表.然后存在一些问题,即某些列是其他表的外键,这会导致更复杂的问题.他们注意到SQL不支持他们正在做的事情,他们必须构建一个小目录.八个表是正确的,但不明智.他们的目的是摆脱Nulls,而不是在每张桌子周围写一个小的子系统.
不熟悉关系数据库建模标准的读者可能会发现IDEF1X表示法对于解释示例中的符号很有用.
通常,产品表保留所有必需列,尤其是FK,每个可选列(每个Nullable列)都放在一个单独的子产品表中.这是我见过的最简单的形式.五张桌子而不是八张桌子.在模型中,四个子产品表是"在6NF"; 主要的产品表是"5NF".
现在我们真的不需要SELECT中的每个代码段都要根据ProductType等来确定它应该构造哪些列,所以我们提供了一个View,它基本上提供了Product表簇的5NF"视图" .
接下来我们需要的是SQL目录扩展的基本原理,这样我们就可以确保各种ProductTypes的规则(数据完整性)在一个地方,数据库中维护,而不依赖于应用程序代码.最简单的目录,你可以逃脱.这是由ProductType驱动的,因此ProductType现在构成该元数据的一部分.你可以在没有目录的情况下实现这个简单的结构,但我不推荐它.
更新
请务必注意,我在数据库中实现了所有业务规则.否则它不是一个数据库(在应用程序代码中实现规则的概念在极端情况下是热闹的,尤其是现在,当我们让花店作为"开发人员"工作时).因此,所有规则等首先实现为SQL声明,CHECK约束,函数等.这保留了所有声明性参照完整性和声明性数据完整性.SQL目录的扩展涵盖了SQL没有声明的区域,然后将它们实现为SQL.作为一个好的数据字典,它做得更多.例如.每次更改表或添加或更改列或它们的特性时,我都不会编写视图,它们是使用简单的代码生成器直接从catalog +扩展创建的.
还有一个非常重要的说明.如果没有完成一个完整而忠实的规范化练习,你就无法实现6NF(或适当的EAV)到5NF.我在每个站点看到的问题是,他们没有真正的5NF状态,他们有部分规范化的混合或根本没有规范化,但他们非常依赖于此.从中创建6NF或EAV是一场灾难.在没有声明性SQL中实现的所有业务规则的情况下创建EAV或6NF 是一场核灾难,燃烧多年.你得到你所付出的.
结束更新.
最后,是的,至少还有四个标准化级别(标准化是一个原则,而不仅仅是对普通形式的引用),可以应用于那个简单的6NF产品集群,提供更多的控制,更少的表格等.我们越深入,目录越广泛.并且性能更高.当你准备好了,只要问一下,我已经建立了模型并在其他答案中发布了详细信息.
nvo*_*gel 30
简而言之,6NF意味着每个关系由候选键加上不超过一个其他(键或非键)属性组成.举个例子,如果ProductCode标识了"item",而其他属性是Description和Price,则6NF模式将包含两个关系(*表示每个关键字):
ItemDesc {ProductCode*, Description}
ItemPrice {ProductCode*, Price}
Run Code Online (Sandbox Code Playgroud)
这可能是一种非常灵活的方法,因为它可以最大限度地减少依赖性.这也是它的主要缺点,特别是在SQL数据库中.SQL使得强制执行许多多表约束变得困难或不可能.使用上述模式,在大多数情况下,将无法强制执行每个产品必须始终具有描述和价格的业务规则.同样,您可能无法强制执行一些应该应用的复合键(因为它们的属性可以拆分为多个表).
因此,在考虑6NF时,您必须权衡哪些依赖关系和完整性规则对您很重要.在许多情况下,您可能会发现坚持使用5NF更加实用和有用,并且不再进行标准化.
我以前一直对6NF持怀疑态度,因为它只是"仅仅"在表格上粘贴了一些时间戳列.
我不太清楚这种明显的误解来自哪里.也许6NF是由Date,Darwen和Lorentzos的"时间数据和关系模式"一书引入的?无论如何,我希望这里的其他答案澄清了6NF不仅限于时态数据库.
我想说的是,尽管6NF"在学术上是可敬的"并且总是可以实现的,但它可能不一定导致每种情况下的最佳设计(而不仅仅是在考虑使用SQL的实现时).即使上述6NF的发现者和支持者似乎也同意如此
克里斯日期:"出于实际目的,坚持5NF(和6NF)."
Hugh Darwen:"围绕约会的6NF分解[不是那个人!]会有点过分......足球俱乐部的最佳设计是...... 5-and-bit-NF!"
休达文:"我们在5NF但不在6NF,5NF就足够了"(几个类似的例子).
然后,我也可以找到相反的证据:
Chris Date:"Darwen和我都觉得有一段时间所有的基础设施都应该在6NF".
实际上,我最近扩展了我们其中一个产品的SQL模式,以添加一个次要功能.我采用了一个6NF来避免可空列,最后得到六个新表,其中大多数(所有?)我的同事会使用一个可以为空的列的表(或者可能扩展现有的表).尽管我证明了几个"助手"存储过程和一个VIEW带有INSTEAD OF触发器的"非规范化" ,但是每个必须在SQL级别使用此功能的编码器都不顾一切地诅咒我:)