你的披萨可以有三种配料类型:
因此,我们订购了两个披萨,并 Select 以下配料:
Pizza Topping Topping Type
-------- ---------- -------------
1 mozzarella cheese
1 pepperoni meat
1 olives vegetable
2 mozzarella meat
2 sausage cheese
2 peppers vegetable
等等,马苏里拉cheese 不可能既是cheese 又是肉!而且香肠也不是cheese !
我们需要防止这类错误,让mozzarella always成为cheese .我们应该使用一个单独的表格,所以我们只在一个地方写下这个事实.
Pizza Topping
-------- ----------
1 mozzarella
1 pepperoni
1 olives
2 mozzarella
2 sausage
2 peppers
Topping Topping Type
---------- -------------
mozzarella cheese
pepperoni meat
olives vegetable
sausage meat
peppers vegetable
这是一个8岁的子元素可能会理解的解释.以下是更具技术性的版本.
BCNF acts differently from 3NF only when there are multiple overlapping candidate keys.
原因是如果Y
是X
的子集,则函数依赖X -> Y
当然是真的.因此,在任何只有一个候选键且在3NF中的表中,它已经在BCNF中,因为没有列(键或非键)在功能上依赖于除该键之外的任何列.
因 for each 披萨都必须有一种配料类型,所以我们知道(披萨,配料类型)是一个候选键.我们也直观地知道,一个给定的浇头不能同时属于不同的类型.所以(披萨、配料)必须是独一无二的,因此也是候选的关键.所以我们有两个重叠的候选键.
我显示了一个异常情况,我们把莫扎里拉cheese 标记为错误的配料类型.我们知道这是错误的,但是使其错误的规则是依赖项Topping -> Topping Type
,该依赖项不是该表的BCNF的有效依赖项.它依赖于不同于整个候选密钥的东西.
因此,为了解决这个问题,我们将Topping Type从披萨表中删除,并使其成为TOPINGS表中的非键属性.