如何理解第5范式?

Har*_*rry 13 database-design relational-database database-normalization

我正在使用两个在线资源来获得对5NF的理解,而没有任何严格的数学和证明.

  1. 关系数据库理论中的五种常规形式的简单指南(作者:肯特.这个似乎已经在他的一篇着作中被CJ Date自己评论和认可)
  2. 第五范式(维基百科文章)

但是,我无法理解这些参考文献中的任何一个!

我们先来看一下Reference#1(Kent's).

它说:"但假设某条规则有效:如果代理商销售某种产品​​,而他代表一家制造该产品的公司,那么他就会为该公司销售该产品."

然后,继续分解原始表(所有表名都由我给出)......

acp(agent, company, product)

-----------------------------
| AGENT | COMPANY | PRODUCT |
|-------+---------+---------|
| Smith | Ford    | car     | 
| Smith | Ford    | truck   | 
| Smith | GM      | car     | 
| Smith | GM      | truck   | 
| Jones | Ford    | car     | 
-----------------------------
Run Code Online (Sandbox Code Playgroud)

...分为3个表:

ac(agent, company)
cp(company, product)
ap(agent, product)

-------------------   ---------------------   ------------------- 
| AGENT | COMPANY |   | COMPANY | PRODUCT |   | AGENT | PRODUCT |
|-------+---------|   |---------+---------|   |-------+---------|
| Smith | Ford    |   | Ford    | car     |   | Smith | car     |
| Smith | GM      |   | Ford    | truck   |   | Smith | truck   |
| Jones | Ford    |   | GM      | car     |   | Jones | car     |
-------------------   | GM      | truck   |   -------------------
                      ---------------------
Run Code Online (Sandbox Code Playgroud)

但我甚至不确定我是否理解上述规则的英语含义.我对上述规则的理解是它的'then'条款完全是多余的!对于,

如果代理商在销售产品

如果该代理人代表制作该产品的公司,

那么,很明显,这个代理商正在为该公司销售该产品.

那么,本声明中的"规则"在哪里?事实上,它对我来说似乎不是一个声明!

从三个表格 - ac,cp和ap - 向后工作 - 似乎规则确实是:"公司可以生产一种或多种产品,代理商可以代表一家或多家公司,并且当代表公司时,他可以或者可能不会出售其所有产品."

但原来的表acp已经捕获了这个规则.所以,我不确定5NF的解释是怎么回事.

我们现在来看一下参考文献#2(维基百科).

它说:但是,假设以下规则适用:"旅行推销员在他的曲目中有某些品牌和某些产品类型.如果品牌B1和品牌B2在他的曲目中,而产品类型P在他的曲目中,那么(假设品牌B1和品牌B2均为产品类型P),旅行商必须提供由B1品牌和B2品牌制造的产品类型P的产品.

再一次,只是按照这条规则的英语含义而不是别的,

如果推销员有品牌B1和B2,产品P和他一起,

如果产品P由B1和B2品牌制造,

然后,为什么他不能像原来的3柱表'spp(推销员,品牌,产品)那样提供品牌B1和B2的产品P,甚至在这个新的'之前服务很好'规则'生效了吗?

有人可以澄清一下吗?

Dam*_*vic 26

看,向后理解事情要容易得多.

首先是5NF ; 表(关系变量)在5NF中,如果分解它不会删除任何冗余.因此,就删除冗余而言,它是最终的NF.

原始表显然有一些冗余.它声称"史密斯代表福特".两次,"史密斯代表通用汽车".两次.

因此,让我们看看是否可以将其分解为两个或更多个投影并减少一些冗余.

让我们开始倒退吧.

  • 公司存在. {COMPANY}

  • 代理存在. {AGENT}

  • 产品存在. {PRODUCT}

  • 公司制造产品.{COMPANY, PRODUCT}

  • 代理人代表公司.{AGENT, COMPANY}

暂停一下; 假设一条规则是"如果代理人代表公司,而公司制造产品,则代理商销售该产品".

这很简单 {AGENT, COMPANY} JOIN {COMPANY, PRODUCT}; 但这会产生一个额外的元组,即(Jones, Ford, truck); 这不是真的,因为琼斯不卖卡车.

因此,并非每个代理商都销售所有产品,因此有必要明确说明.

  • 代理销售产品.{AGENT, PRODUCT}

现在,如果我们加入

{AGENT, COMPANY} JOIN {COMPANY, PRODUCT} JOIN {AGENT, PRODUCT}

通过连接消除了额外的元组{AGENT, PRODUCT}.

为了直观地掌握事物,可以对规则进行一些修改.

原版的

如果代理商销售某种产品​​,并且他代表制造该产品的公司,那么他就会为该公司销售该产品.

修改(含义相同)

如果代理商销售产品,代理商代表公司,并且公司制造该产品,则代理商为该公司销售该产品.

解释(从上面的要点替代)

如果 {AGENT, PRODUCT}{AGENT, COMPANY}{COMPANY, PRODUCT}{AGENT, COMPANY, PRODUCT}.

因此,规则允许连接发生 - 因此分解.

现在将它与原始表的谓词进行比较:

代理商代表公司并销售公司制造的一些 产品.

与规则不同,因此它会违反规则的异常 - 请参阅Bill Karwin的例子.


编辑(见下面的评论)

假设我们有原始表,但不是规则.

显然表中有一些冗余,所以我们可能想知道是否有办法以某种方式消除冗余 - 通常的方法是分解为表的投影.

因此,经过一些修补,我们发现它可以被分解成{AGENT, PRODUCT}, {AGENT, COMPANY}, {COMPANY, PRODUCT}.当前数据肯定允许 - 根据您的示例.

我们这样做,并且只要对"哪个代理商销售哪个产品来自哪个公司?"感兴趣答案很简单

{AGENT, COMPANY} JOIN {COMPANY, PRODUCT} JOIN {AGENT, PRODUCT}

然后本田出现了,他们也生产汽车和卡车.好了,没有问题存在,只需插入(Honda, truck) , (Honda, car){COMPANY, PRODUCT}.

然后史密斯决定出售本田汽车,但不是卡车.对不起,没办法,哎呀!因为他已经出售汽车和卡车,如果他想代表本田,他必须出售两者.

因为我们会有元组

(Smith, Honda) (Honda, truck) (Smith, truck)
               (Honda, car)   (Smith, car)
Run Code Online (Sandbox Code Playgroud)

所以我们已经介绍了规则!真的不想 - 只是试图摆脱一些冗余.

现在的问题是,原始数据集只是一个侥幸,还是一个规则的结果,这个规则在数据库之外以某种方式强制执行?

作者(肯特)声称该规则存在且设计与之不符.当然,原始表(Smith, Honda, car)只接受- 不要求也不是问题(Smith, Honda, truck).


理论观点(如果无聊则忽略)

规则

If {AGENT, PRODUCT} and {AGENT, COMPANY} and {COMPANY, PRODUCT} then {AGENT, COMPANY, PRODUCT}; 对于每一个(Agent, Company, Product)三胞胎.

明确声明加入依赖

* { {AGENT, COMPANY}, {COMPANY, PRODUCT}, {AGENT, PRODUCT} }

保留原始表.


正如经常说的那样,这种情况很少见; 实际上非常罕见,甚至教科书的例子都必须引入奇怪的规则来解释基本思想.


编辑II(有趣的部分,但可能有助于理解)

假设该规则不存在,并且明确要求任何代理人可以从任何公司出售他想要的东西 - 因此该规则将是完全错误的.

在那种情况下,我们有原始表

{AGENT, COMPANY, PRODUCT}

我认为:

  1. 这是关键,它在BCNF.

  2. 它不能被分解(当前数据可能允许它,但未来不会).

  3. 它在BCNF,所有关键,它不能被分解,因此它在5NF.

  4. 它在5NF并且是全键,因此它在6NF.

因此,规则的存在或不存在确定表是否在BCNF或6NF中 - 相同的表是相同的数据.


Bil*_*win 11

所有正常形式都旨在避免异常,即数据中的逻辑不一致.

当您违反第5范式时,可能存在异常,由此关系表示:

-----------------------------
| AGENT | COMPANY | PRODUCT |
|-------+---------+---------|
| Smith | Ford    | car     | 
| Smith | Ford    | truck   | 
| Smith | GM      | car     | 
| Jones | Ford    | car     | 
| Jones | GM      | truck   | 
-----------------------------
Run Code Online (Sandbox Code Playgroud)

因此我们知道琼斯为通用汽车和福特工作,我们知道琼斯销售汽车和卡车.我们知道(来自史密斯)通用汽车生产汽车.那么为什么不排[Jones, GM, car]?那是一个异常现象.琼斯应该出售转基因汽车,但这张表中没有任何内容可以保持一致性.

问题来自于尝试使用一种关系来表示多个独立事实.
如果我们不是代表这些独立的事实,作为独立的关系ac,cpap,然后我们删除异常的可能性.


你的评论:

出于这个例子的目的,我们假设销售人员有动力出售他能做的任何事情.如果他可以出售一种类型的车辆,并且他在一家公司工作,并且该公司生产这种类型的车辆,那么销售人员肯定会出售它.

William Kent的文章中阐述了这一前提:

但是假设某个规则有效:如果代理商销售某种产品​​,并且他代表制造该产品的公司,那么他就会为该公司销售该产品.

因此,基于这个前提,隐含的是每个可能的有效组合都应该在三列表中产生一行.这是我们希望数据满足的业务规则.

但是,如果我们的单个表不包含与该前提一致所必需的行之一,则它无法表示业务规则.基本上,因为它引入了冗余存储"事实"的可能性.

通过将事实分成三个表,每个事实只存储一次.三个更简单的表之间的JOIN结果自然产生一个类似于原始三列表的关系,除了保证没有异常.


Erw*_*out 8

"如果代理商在销售产品

如果该代理人代表制作该产品的公司,

那么,很明显,这个代理商正在为该公司销售该产品."

这完全错了.完全.再考虑一下.

福特出租车.福特制造了自行车.通用汽车制造出租车.GM制造自行车.

我代表福特.我代表GM.我卖出租车.我卖自行车.

现在,在以下情况下,所有这8个陈述都是正确的:

我卖出租车,但只有福特出售.我卖自行车,但只有转基因类.

答:是的.

事实上,我代表福特购买某些产品,而我为一些制造商销售自行车而福特生产的自行车,这在逻辑上并不意味着我销售福特自行车.

编辑:进一步澄清并尝试解决实际问题.5NF

acp设计在5NF,并且不能(不能)被分解的情况和ACP设计不在5NF中并且必须被分解的情况之间的区别恰恰在于是否存在业务规则大意是DOES "在逻辑上意味着我卖福特bycicles"(坚持的例子). 仅逻辑并没有给我们这样的规则,但企业可以添加他们想要的所有规则.

如果这样的规则生效,那么acp设计中的信息("我卖福特bycicles")确实可以从其他设计中获得逻辑推导(不仅仅凭借逻辑而是凭借规则应用),而另一个设计必须选择设计(选择记录逻辑上可导出的信息构成冗余,以及它可以从中导出的"基本"信息,因此构成对某些NF的违反).

如果没有这样的规则有效,那么acp设计中的信息在逻辑上不能从其他任何东西中导出,那么必须 "单独"地说明这些信息.没有这样的规则意味着没有可衍生性/冗余,因此(相当松散和懒散地说)没有违反NF.