Arn*_*tta 148 database relational-database 3nf database-normalization
我已经阅读了引用: 数据取决于键[1NF],整个键[2NF],只有键[3NF].
但是,我无法理解3.5NF或BCNF.这是我的理解:
那么为什么有些3NF表不在BCNF中呢?我的意思是,3NF引用明确地说"除了密钥之外",意味着所有属性仅仅依赖于主键.毕竟,主键是候选键,直到它被选为我们的主键.
如果到目前为止我的理解有任何不妥之处,请纠正我并感谢您提供的任何帮助.
Bil*_*win 157
你的披萨可以有三种顶级类型:
所以我们点两个比萨饼并选择以下配料:
Pizza Topping Topping Type
-------- ---------- -------------
1 mozzarella cheese
1 pepperoni meat
1 olives vegetable
2 mozzarella meat
2 sausage cheese
2 peppers vegetable
Run Code Online (Sandbox Code Playgroud)
等一下,马苏里拉奶酪不能既是奶酪又是肉!而香肠不是奶酪!
我们需要防止这些错误,使马苏里拉奶酪永远是奶酪.我们应该为此使用一个单独的表,所以我们只在一个地方写下这个事实.
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
Run Code Online (Sandbox Code Playgroud)
这是一个8岁的孩子可能理解的解释.这是更技术性的版本.
仅当存在多个重叠候选键时,BCNF与3NF的行为不同.
原因是如果函数依赖是其子集,则函数依赖性X -> Y当然是正确Y的X.因此,在任何只有一个候选键并且在3NF中的表中,它已经在BCNF中,因为没有列(键或非键)在功能上依赖于除该键之外的任何东西.
因为每个披萨必须具有每种顶部类型中的一种,我们知道(Pizza,Topping Type)是候选键.我们也直观地知道给定的浇头不能同时属于不同的类型.因此(Pizza,Topping)必须是唯一的,因此也是候选键.所以我们有两个重叠的候选键.
我展示了一个异常,我们将mozarella标记为错误的浇头类型.我们知道这是错误的,但是错误的规则是依赖关系Topping -> Topping Type,它不是BCNF对此表的有效依赖关系.它是对整个候选键之外的其他东西的依赖.
因此,为了解决这个问题,我们从Pizzas表中取出Topping Type,并将其作为Toppings表中的非键属性.
nvo*_*gel 87
细微差别在于3NF区分了键和非键属性(也称为非素数属性),而BCNF则没有.
使用Zaniolo对3NF 的定义可以得到最好的解释,这相当于Codd的:
对于R满足的每个非平凡FD(X-> A),满足下列条件中的至少一个条件的关系R为3NF:
(a)X是R的超级密钥,或
(b)A是R的关键属性
BCNF要求(a)但不将(b)视为其自身的特殊情况.换句话说,BCNF要求每个重要的决定因素都是超级密钥,即使其依赖属性恰好是密钥的一部分.
关系R在BCNF中如果对于满足R的每个非平凡FD(X-> A),则满足以下条件:
(a)X是R的超级密钥
因此BCNF更严格.
差异是如此微妙,许多人非正式地描述为3NF实际上是BCNF.例如,你在这里说3NF意味着"数据取决于密钥[s] ......除了密钥[s]之外什么都没有",但这实际上是BCNF的非正式描述而不是3NF.3NF可以更准确地描述为" 非关键数据取决于密钥...而且只有密钥".
你还说:
3NF引用明确地说"除了关键",意味着所有属性仅依赖于主键.
这太过于简单化了.3NF和BCNF以及所有正常表格都关注所有候选键和/或超级键,而不仅仅是一个"主键".
AGé*_*der 23
使用BCNF定义
当且仅当对于它的每个依赖关系X→Y时,至少有下列条件之一:
和3NF的定义
当且仅当对于其每个功能依赖关系X→A时,至少下列条件之一成立:
而
哪里
也就是说,候选键的任何部分子集(除了全集之外的任何非平凡子集)都可以在功能上依赖于除超级密钥之外的任何其他东西.
不在BCNF中的表/关系受到异常的影响,例如另一个用户在比萨示例中提到的更新异常.不幸,
目前可以在维基百科上的" 3NF表不符合BCNF(Boyce-Codd普通形式) "中找到差异的示例,其中下表符合3NF但不符合BCNF,因为"网球场"(部分键/主要属性)取决于在"Rate Type"(一个不是超级键的部分键/素数属性)上,这是我们可以通过询问数据库的客户,网球俱乐部来确定的依赖:
今天的网球场预订(3NF,不是 BCNF)
Court Start Time End Time Rate Type
------- ---------- -------- ---------
1 09:30 10:30 SAVER
1 11:00 12:00 SAVER
1 14:00 15:30 STANDARD
2 10:00 11:30 PREMIUM-B
2 11:30 13:30 PREMIUM-B
2 15:00 16:30 PREMIUM-A
Run Code Online (Sandbox Code Playgroud)
该表的超级键是:
S1 = {Court, Start Time}
S2 = {Court, End Time}
S3 = {Rate Type, Start Time}
S4 = {Rate Type, End Time}
S5 = {Court, Start Time, End Time}
S6 = {Rate Type, Start Time, End Time}
S7 = {Court, Rate Type, Start Time}
S8 = {Court, Rate Type, End Time}
ST = {Court, Rate Type, Start Time, End Time}, the trivial superkey
Run Code Online (Sandbox Code Playgroud)
3NF问题:部分键/素数属性"Court"依赖于超级键以外的其他内容.相反,它取决于部分键/素数属性"速率类型".这意味着如果我们升级法院,用户必须手动更改费率类型,或者如果想要应用费率更改,则手动更改法院.
(在技术方面,我们不能保证不会违反"费率类型" - >"法院"功能依赖.)
BCNF解决方案:如果我们想将上表放在BCNF中,我们可以将给定的关系/表分解为以下两个关系/表(假设我们知道费率类型仅取决于法院和成员身份,我们可以通过询问我们的数据库的客户,网球俱乐部的所有者发现:
费率类型(BCNF和较弱的3NF,BCNF暗示)
Rate Type Court Member Flag
--------- ----- -----------
SAVER 1 Yes
STANDARD 1 No
PREMIUM-A 2 Yes
PREMIUM-B 2 No
Run Code Online (Sandbox Code Playgroud)
今天的网球场预订(BCNF和较弱的3NF,由BCNF暗示)
Member Flag Court Start Time End Time
----------- ----- ---------- --------
Yes 1 09:30 10:30
Yes 1 11:00 12:00
No 1 14:00 15:30
No 2 10:00 11:30
No 2 11:30 13:30
Yes 2 15:00 16:30
Run Code Online (Sandbox Code Playgroud)
解决的问题:现在,如果我们升级法院,我们可以保证费率类型将反映这一变化,我们不能为法院收取错误的价格.
(在技术方面,我们可以保证不会违反功能依赖"费率类型" - >"法院".)
jfe*_*ard 11
这是一个老问题,有很有价值的答案,但我仍然有点困惑,直到我找到一个现实生活中的例子来显示 3NF 的问题。可能不适合8岁的孩子,但希望有帮助。
明天我将在一次季度家长/老师会议上与我大女儿的老师见面。这是我的日记的样子(名称和房间已更改):
Teacher | Date | Room
----------|------------------|-----
Mr Smith | 2018-12-18 18:15 | A12
Mr Jones | 2018-12-18 18:30 | B10
Ms Doe | 2018-12-18 18:45 | C21
Ms Rogers | 2018-12-18 19:00 | A08
Run Code Online (Sandbox Code Playgroud)
每个房间只有一名老师,而且他们从不移动。如果您看一下,您会发现: (1) 对于每个属性Teacher, Date, Room,每行只有一个值。(2) 超级键是:(Teacher, Date, Room)、(Teacher, Date)和(Date, Room),候选键显然是(Teacher, Date)和(Date, Room)。
(Teacher, Room)不是超级键,因为我将在下个季度完成该表,并且我可能会有像这样的一行(史密斯先生没有动!):
Teacher | Date | Room
---------|------------------| ----
Mr Smith | 2019-03-19 18:15 | A12
Run Code Online (Sandbox Code Playgroud)
我们可以得出什么结论?(1) 是 1NF 的非正式但正确的表述。从(2)我们看到不存在“非素数属性”:2NF和3NF是免费给出的。
我的日记是3NF。好的!不。并非如此,因为没有数据建模者会在数据库模式中接受这一点。该Room属性依赖于该Teacher属性(再次强调:教师不动!),但模式并未反映这一事实。一个理智的数据建模师会做什么?将表分成两部分:
Teacher | Date
----------|-----------------
Mr Smith | 2018-12-18 18:15
Mr Jones | 2018-12-18 18:30
Ms Doe | 2018-12-18 18:45
Ms Rogers | 2018-12-18 19:00
Run Code Online (Sandbox Code Playgroud)
和
Teacher | Room
----------|-----
Mr Smith | A12
Mr Jones | B10
Ms Doe | C21
Ms Rogers | A08
Run Code Online (Sandbox Code Playgroud)
但 3NF 不处理素数属性依赖性。这就是问题所在:在某些情况下,3NF 合规性不足以确保良好的表模式设计。
使用 BCNF,您不必关心该属性是否是 2NF 和 3NF 规则中的素数属性。对于每个非平凡的依赖关系(子集显然是由它们的超集决定的),行列式是一个完整的超级键。换句话说,除了完整的超级密钥(不包括琐碎的 FD)之外,没有任何东西是由其他东西决定的。(有关正式定义,请参阅其他答案)。
一旦Room取决于Teacher,Room必须是Teacher(事实并非如此) 或Teacher必须是超级键(我的日记中不是这种情况,但拆分表时就是这种情况)。
总结一下:BNCF 比 3NF 更严格,但在我看来更容易掌握:
所有的好答案。简而言之 [BCNF] 没有部分密钥可以依赖于密钥。
即,候选键的任何部分子集(即,除完整集外的任何非平凡子集)都不能在功能上依赖于某个候选键。
\xe2\x80\x98 smartnut007 \xe2\x80\x99、\xe2\x80\x98 Bill Karwin \xe2\x80\x99 和 \xe2\x80\x98 sqlvogel \xe2\x80\x99 的答案非常好。不过,让我提出一个有趣的观点。
\n\n嗯,我们有主键和非主键。
\n\n当我们关注非素数如何依赖素数时,我们会看到两种情况:
\n非素数可以是相关的,也可以不是。
\n\n当不依赖时:可以存在无依赖或传递依赖
\n\n素数之间的依赖关系又如何呢?
\n现在你看,我们\xe2\x80\x99并没有通过第二个或第三个NF来解决素数之间的依赖关系。\n进一步的这种依赖关系(如果有的话)是不可取的,因此我们\xe2\x80\x99有一个单一的规则来解决这个问题。这就是BCNF。
\n\n参考Bill Karwin的帖子中的示例,您\xe2\x80\x99 会注意到 \xe2\x80\x98 Topping \xe2\x80\x99 和 \xe2\x80\x98 Topping Type \xe2\x80\ x99 是主键并且具有依赖性。如果它们是有依赖性的非素数,那么 3NF 就会开始发挥作用。
\n\n笔记:
\n BCNF 的定义非常通用,并且没有区分素数和非素数的属性。然而,上述思维方式有助于理解即使在第二次和第三次 NF 之后,某些异常是如何渗透的。
\n\n高级主题:将通用 BCNF 映射到 2NF 和 3NF
\n现在我们知道 BCNF 提供了一个通用定义,而不涉及任何素数/非素数属性,让我们看看 BCNF 和 2/3 NF 是如何相关的。
\n首先,BCNF 要求(除了微不足道的情况)对于每个功能依赖X -> Y(FD),X 应该是超级键。\n如果您只考虑任何 FD,那么我们有三种情况 - (1) X 和 Y非素数,(2) 两者都是素数,并且 (3) X 素数和 Y 非素数,丢弃(无意义的)情况 X 非素数和 Y 素数。
\n对于情况 (1),3NF 负责处理。
\n对于情况 (3),由 2NF 处理。
\n对于情况(2),我们发现BCNF的使用
\n| 归档时间: |
|
| 查看次数: |
184815 次 |
| 最近记录: |