15

我使用两个在线资源来了解 5NF,没有任何严格的数学和证明。

  1. 关系数据库理论中五种范式的简单指南(由 Kent 撰写。这本书似乎在他的一篇著作中得到了 CJ Date 本人的审查和认可)
  2. 第五范式(维基百科文章)

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

让我们首先检查参考文献#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     | 
-----------------------------

...分成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   |   -------------------
                      ---------------------

但我什至不确定我是否理解上述规则的英语含义。我对上述规则的理解是它的“then”子句是完全多余的!为了,

如果代理商正在销售产品

如果该代理代表生产该产品的公司,

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

那么,这个声明中的“规则”在哪里?事实上,这对我来说似乎是一个非陈述!

从三个表(ac、cp 和 ap)向后推算,规则似乎真的是:“一家公司可能生产 1 种或多种产品,代理可能代表 1 家或更多公司,当代表一家公司时,他可能或可能不会出售其所有产品。”

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

现在让我们检查参考文献#2(维基百科)。

它说:但是,假设以下规则适用:“一个旅行推销员在他的曲目中具有某些品牌和某些产品类型。如果品牌 B1 和品牌 B2 在他的曲目中,并且产品类型 P 在他的曲目中,那么 (假设品牌 B1 和品牌 B2 都生产产品类型 P),旅行推销员必须提供产品类型 P 的产品,即品牌 B1 生产的产品和品牌 B2 生产的产品。”

再一次,仅按照这条规则的英语含义,仅此而已,

如果一个推销员有品牌 B1 和 B2,以及他的产品 P,

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

那么,为什么他不能像原来的 3 列表“sbp(销售员、品牌、产品)”一样提供品牌 B1 和 B2 的产品 P,该表甚至在这个新的 '规则”生效了吗?

有人可以澄清一下吗?

4

3 回答 3

28

看,倒过来理解事情要容易得多。

首先是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}

因此,该规则允许连接发生——因此也允许分解。

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

代理代表一家公司并销售该公司生产的一些 产品

与规则不同,因此它对违反规则的异常情况开放——参见比尔卡尔文的例子。


编辑(见下面的评论)

假设我们有原始表,但没有规则

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

所以,经过一番修改,我们发现它可以分解为{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)

所以我们引入了规则!真的不想——只是想摆脱一些冗余。

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

作者 (Kent) 声称该规则存在并且设计与它不匹配。当然,原始表只接受(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} }

适用于原始表。


正如人们常说的,这样的情况很少见。实际上如此罕见,以至于即使是教科书示例也必须引入奇怪的规则才能解释基本思想。


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

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

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

{AGENT, COMPANY, PRODUCT}

我认为:

  1. 作为所有关键,它在 BCNF 中。

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

  3. 它在 BCNF 中,全是密钥,不能分解,因此在 5NF 中。

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

因此,规则的存在与否决定了表是在 BCNF 还是 6NF 中——同一个表相同的数据。

于 2013-08-03T12:29:00.937 回答
12

所有正常形式都是为了避免异常,即数据中的逻辑不一致。

当您违反由以下关系表示的第 5 范式时,可能会出现异常情况:

-----------------------------
| AGENT | COMPANY | PRODUCT |
|-------+---------+---------|
| Smith | Ford    | car     | 
| Smith | Ford    | truck   | 
| Smith | GM      | car     | 
| Jones | Ford    | car     | 
| Jones | GM      | truck   | 
-----------------------------

所以我们知道琼斯为通用汽车和福特工作,我们知道琼斯销售汽车和卡车。我们知道(从史密斯那里)通用汽车制造汽车。那么为什么没有一行[Jones, GM, car]呢?这是一个反常现象。琼斯应该卖通用汽车,但这张表中没有任何东西可以保持一致。

问题来自于试图使用一种关系来表示多个独立的事实。
如果我们将这些独立的事实表示为独立的关系accpap,那么我们消除了异常的可能性。


回复您的评论:

为了这个例子的目的,我们假设一个推销员有动力去卖他能卖的任何东西。如果他卖一种车,他在一家公司工作,公司生产这种车,那推销员肯定会卖。

这个前提在威廉肯特的文章中陈述:

但是假设某条规则生效:如果代理销售某种产品​​,并且他代表一家生产该产品的公司,那么他为该公司销售该产品。

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

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

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

于 2013-08-03T07:42:10.587 回答
8

“如果代理商正在销售产品

如果该代理代表生产该产品的公司,

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

这是完全错误的。完全。再想一想。

福特制造出租车。福特制造自行车。通用汽车制造出租车。通用汽车制造自行车。

我代表福特。我代表通用汽车。我卖出租车。我卖自行车。

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

我卖出租车,但只卖福特那种。我卖自行车,但只卖 GM 那种。

答:是的。

我代表福特的某些产品,我为某些制造商销售自行车,而福特制造自行车,这在逻辑上并不意味着我销售福特自行车。

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

acp 设计在 5NF 中且不得(不能)分解的情况与 ACP 设计不在 5NF 中且必须分解的情况之间的区别恰恰在于是否存在BUSINESS规则效果确实“在逻辑上暗示我卖福特自行车”(坚持这个例子)。 单靠逻辑并没有给我们这样的规则,但是企业可以添加他们想要的所有规则。

如果这样的规则有效,那么 acp 设计中的信息(“我卖福特自行车”)确实可以从另一个设计和另一个设计中逻辑推导出来(不仅通过逻辑,而是通过应用规则)必须选择设计(选择记录逻辑上可导出的信息构成了可导出的“基本”信息的冗余,因此构成了对某些 NF 的违反)。

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

于 2013-08-07T20:26:14.573 回答