我已经分解了追踪员工的关系以及他们在酒店工作的时间。原始关系如下
R(national insurance number, contract Number, hours, eName, hotel Number, hotel Location)
重写为
R(A, B, C, D, E, F)
我找到了功能依赖
F:(A->D, E->F, AB->C, B->E, BA->E)
由此我创建了以下3个表
1.
Employees:
national insurance number(A)
eName(D)
PRIMARY KEY(A)
2.
Works at:
contract Number(B)
Hours(C)
national insurance number(A)
PRIMARY KEY(B, AND A)
3.
Hotel:
contract Number(B)
hotel Number(E)
hotel Location(F)
PRIMARY KEY(B)
在我的第三张表中,我有一个主键,可以确定酒店的数量和位置。但酒店号码也可以决定酒店 地点。我应该将酒店位置移到一张只有酒店号码的新桌子吗?这将占用更多空间,但是有必要达到3RD正常形式吗?
答案 0 :(得分:1)
当假设您派生的FD正确且完整时,要在您的设置中获得第3范式,必须将Hotel(B,E,F) { B->E, E->F }
分为HotelContract(B,E) { B->E }
和Hotel(E,F) { E->F }
。
正式地,在{ B->E, E->F }
中,B
是(唯一)键,E
是“非素数”属性(即不是任何键的一部分),因此F
通过密钥的非主要属性传递依赖。这违反了第3范式。
如果模式Hotel(B,E,F) { B->E, E->F }
违反了3NF,则会出现“删除异常”,即从Hotel
删除元组时,您丢失的信息超出了必要的数量。假设Hotel
的以下扩展名为:
Hotel
B | E | F
---|---|---
b1 | e1| f1
b2 | e2| f2
当您删除元组(b2,e2,f2)
时,您会丢失酒店e2
在f2
中的信息,尽管您只想删除合同。
更糟糕的是,当你将计划翻译成
时Hotel:
contract Number(B)
hotel Number(E)
hotel Location(F)
PRIMARY KEY(B)
然后你实际上省略了FD E->F
,这将允许同一酒店e1
获得两个不同的位置,例如f1
和f2
:
Hotel
B | E | F
---|---|---
b1 | e1| f1
b2 | e1| f2 -> permitted by your scheme, but not intended!
因此,按照介绍中的建议拆分表格。
答案 1 :(得分:1)
看起来你是对的。酒店需要在单独的桌子上。
此外,我猜员工有可能在多家酒店办理多份合约,而且一家酒店可能有多份员工合约。
所以,对我来说,标准化形式看起来像:
1. Employees:
national insurance number(A)
eName(D)
PRIMARY KEY(A)
2. Hotels:
hotel Number(E)
hotel Location(F)
PRIMARY KEY(E)
3. Contracts:
contract Number(B)
hotel Number(E)
PRIMARY KEY(B)
FOREIGN KEY(Hotels.E)
4. Works at:
work at(G),
national insurance number(A)
contract Number(B)
Hours(C)
PRIMARY KEY(G)
FOREIGN KEY(Employees.A)
FOREIGN KEY(Contracts.B)