如何理解第5范式?

时间:2013-08-03 05:54:40

标签: database-design relational-database database-normalization

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

  1. A Simple Guide to Five Normal Forms in Relational Database Theory(肯特。这个似乎已经在他的一篇着作中得到了审查和认可,而不是CJ Date本人)
  2. Fifth Normal Form(维基百科文章)
  3. 但是,我无法理解其中任何一个参考文献!

    让我们先来看一下参考文献#1(肯特)。

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

    然后继续分解原始表格(所有表格都由我提供)......

    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'子句完全是多余的!对于,

    IF 代理商正在销售产品

    AND

    IF 此代理商代表制作该产品的公司

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

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

    从三个表 - ac,cp和ap - 向下工作 - 似乎规则确实是:“公司可以生产1个或更多产品,代理商可能代表1个或更多公司,以及何时代表一家公司,他可能会或可能不会销售其所有产品。“

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

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

    它说:然而,假设以下规则适用:“旅行推销员在他的曲目中有某些品牌和某些产品类型。如果品牌B1和品牌B2在他的保留节目中,产品类​​型P是然后(假设品牌B1和品牌B2都制作产品类型P),旅行推销员必须提供由B1品牌和B2品牌制造的P型产品。“

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

    IF 推销员有品牌B1和B2,产品P有他,

    IF 产品P由B1和B2品牌生产,

    那么,为什么他不能像原来的3柱表'sbp(推销员,品牌,产品)那样提供B1和B2品牌的产品P. “即使在这个新的'规则'生效之前,它还能很好地服务吗?

    请有人澄清一下吗?

3 个答案:

答案 0 :(得分:26)

看,向后理解这件事要容易得多。

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

原始表显然有一些冗余。它声称​​" Smith代表福特。" 两次," Smith代表GM。" 两次。

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

让我们开始倒退。

  • 公司存在。 {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}。当前数据肯定允许 - 根据您的示例。

我们这样做,并且只要对&#34;哪个代理商销售哪个产品来自哪个公司感兴趣?&#34; 答案就是

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

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

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

因为我们会有元组

(Smith, Honda) (Honda, truck) (Smith, truck)
               (Honda, car)   (Smith, car)

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

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

作者(肯特)声称该规则存在且设计与之不符。当然,原始表格仅接受(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。

  5. 因此,规则的存在或不存在决定了表是在BCNF还是6NF - 相同的表是相同的数据。

答案 1 :(得分:11)

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

当您违反第5种正常形式时会出现异常现象,由此关系表示:

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

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

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


重新评论:

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

这一前提在William Kent的文章中说明:

  

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

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

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

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

答案 2 :(得分:8)

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

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

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

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

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

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

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

我出售出租车,但只有福特出售。 我卖的是自行车,但只有GM类。

答案:是的。

我代表福特购买某些产品而我为一些制造商销售自行车而福特生产的自行车这一事实并不逻辑上暗示我出售福特自行车。

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

acp设计在5NF,并且不能(不能)分解的情况和ACP设计不在5NF的情况之间的区别,并且必须被分解,正是在是否存在业务规则实际上 DOES “逻辑上暗示我出售福特自行车”(坚持这个例子)。 仅逻辑并没有给我们这样的规则,但企业可以添加他们想要的所有规则。

IF 这样的规则有效,那么acp设计中的信息(“我卖福特bycicles”)确实可以在逻辑上推导出来(不仅仅凭借逻辑而是凭借规则应用)来自其他设计,并且必须选择其他设计(选择记录逻辑上可导出的信息构成可以从其导出的“基本”信息的冗余,因此构成违反某些NF)。

IF 没有这样的规则生效,那么acp设计中的信息在逻辑上不能从其他任何东西中导出,那么必须被陈述的信息“个别”。没有这样的规则意味着没有可导性/冗余,因此(相当松散和懒散地说话)没有违反NF。