【问题标题】:3nf functional dependency in wiki's examplewiki 示例中的 3nf 函数依赖
【发布时间】:2013-05-18 06:32:55
【问题描述】:

我阅读了关于 3nf 的 wiki https://en.wikipedia.org/wiki/Third_normal_form

这是wiki给出的例子

Tournament Winners
Tournament              Year    Winner          Winner Date of Birth
Indiana Invitational    1998    Al Fredrickson  21 July 1975
Cleveland Open          1999    Bob Albertson   28 September 1968
Des Moines Masters      1999    Al Fredrickson  21 July 1975
Indiana Invitational    1999    Chip Masterson  14 March 1977

它说the non-prime attribute Winner Date of Birth is transitively dependent on the candidate key {Tournament, Year} via the non-prime attribute Winner

我认为函数依赖是这样的

for two row X1 , X2 if X1.col1 = X2.col1 and 
X1.col2 = X2.col2, then col1 -> col2

我无法理解获胜者的出生日期->获胜者(可能有相同生日和相同名字的人?) 获胜者可以 -> 候选键 {Tournament, Year} 给定获胜者名称 Al Fredrickson,可能是 1998 年印第安纳邀请赛或 1999 年得梅因大师赛)

那么,它是如何跳到结论的呢?

【问题讨论】:

  • 有问题的非键依赖是 {Winner}->{Date of Birth},而不是 {Date of Birth}->{Winner}
  • +1 到 sqlvogel。这是正确的。但是我们怎么知道没有两个都叫 Al Fredrickson 的酒商呢?在那种情况下,他们很可能有不同的出生日期。使用名称作为人的代理是一个坏主意,它会使 wiki 条目更弱。
  • 确实如此,除非明确列出了您实际想要执行的 FD,否则此类示例始终没有实际意义。实际上,您肯定不会将名字作为获胜者的标识符,但在一个示例中,它比发明一些任意数字来代替它更简洁明了。

标签: database database-design relational-database third-normal-form


【解决方案1】:

非正式地,functional dependency 表示左侧的一个值不能在右侧产生多个值,即使左侧存在多行也是如此。1

因此,在 Wikipedia 示例中,存在函数依赖关系 Winner -> Winner Date of Birth,这仅仅是因为同一个获胜者不能有不同的出生日期,即使他/她存在于多行中(因为他/她赢得了多个锦标赛)。

因为...

  • {Tournament, Year} -> Winner(因为一场比赛不能有多个获胜者)
  • Winner -> Winner Date of Birth(如上所述)
  • 不是 Winner -> {Tournament, Year}(因为一个人可以赢得多个比赛)

...那么by definition 存在传递依赖。

我无法理解获胜者的出生日期->获胜者(可能有相同生日和相同名字的人?)

你改变了方向。功能依赖不是“来自”单个值,而是“朝向”它。因此Winner -> Winner Date of Birth,但不是 Winner Date of Birth -> Winner

顺便说一句,这个模型中不能有两个名字不同的人。更好(更现实)的模型可能会使用代理键来识别人员,从而允许重复名称。


1 符合“函数”的数学概念。无论您“调用”一个函数多少次(即有多少行包含 f.d. 左侧),它总是产生相同的“结果”(f.d. 右侧)。如果它可以产生多个结果,那它就不是一个函数,而是一个“关系”。

【讨论】:

    【解决方案2】:

    据我了解:
    对于任何 {Tournament, Year},您只有一位获胜者。每位获奖者只有一个出生日期。 Wiki 声称这可能导致漏洞:
    假设您输入了一个新行:{"Stupid Competition", "2013", "Al Fredrickson", "21 July 2012"} - 您输入了错误的出生日期!
    如果您保留另一个表 {WinnerID, WinnerBithday},您将阻止它。

    【讨论】:

      【解决方案3】:

      如果同一获奖者出生日期不同怎么办?那么有可能如何预防呢?

      从基地

      因为表格中的每一行都需要告诉我们谁赢得了特定的 特定年份的锦标赛,复合键 {Tournament, Year} 是保证唯一标识行的最小属性集。也就是说,{Tournament, Year} 是表的候选键。

      如果关系 R 将添加相同的获胜者姓名和不同的出生日期,那么它将为表创建另一个唯一记录,但不应该这样做。我们需要唯一的记录,但这表明具有两个不同出生日期的相同获胜者可以存在于一个表中。

      即使我们想到重复出生日期(对于获胜者),我们也可以 将该表拆分为另一个表,并可以存储{winner,winner date of 出生} 以防止像 wiki 所示的重复。

      参考

      因为没有什么可以阻止同一个人被展示 不同记录上的不同出生日期。

      这就是为什么它需要创建另一个表来防止重复。

      【讨论】:

        猜你喜欢
        • 2017-04-02
        • 2015-07-27
        • 2016-10-11
        • 1970-01-01
        • 1970-01-01
        • 2014-01-02
        • 1970-01-01
        • 1970-01-01
        • 2010-10-19
        相关资源
        最近更新 更多