Table 第三范式,但有明显的冗余
Table in 3rd normal form, yet with obvious redundancies
假设以下 "Reservations" table 有两列 Reservation_Number 和 Guest_Name。 Reservation_Number 是唯一的候选键:
Reservation_Number Guest_Name
------------------ ------------
1 john smith
2 john smith
3 john smith
4 jane doe
5 bob anderson
我的问题是这个 table 是否符合第三范式?
- 好像没有违反第一范式。当 table 具有主键并且每个属性的域仅包含原子值,并且每个属性的值仅包含来自该域的单个值时,它处于 1NF 中。在此示例中,Reservation_Number 是主键,并且 Reservation_Number 和 Guest_Name 都满足原子条件。
- 好像没有违反第二范式。当 table 在 1NF 中时,它在 2NF 中,并且 table 的每个非主要属性都依赖于每个候选键的整体。 Guest_Name 是唯一的非主属性,它完全依赖于唯一的候选键,即 Reservation_Number。
- 好像没有违反第三范式。当 table 处于 2NF 时,它处于 3NF,并且 table 的每个非素数属性都非传递地依赖于 table 的每个超键。唯一的非主属性 Guest_Name 非传递地依赖于唯一的超级键,即 Reservation_Number。
然而,这里有冗余table。我知道我可以通过以下方式删除这些冗余:
a) 使用 Guest_Id 和 Guest_Name 列创建访客 table。
b) 将预订 table 中的 Guest_Name 替换为 Guest_Id FK。
但我的问题是,原始预订 table 怎么可能是第三范式,但在 Guest_Name 列中却有冗余?如果它违反了正常形式,那么如何以及为什么?请帮忙!
您的示例不会违反第二和第三范式,但是如果您添加一列 Guest_Telephone
会怎么样。那么第三范式就会被违反,因为你在 Guest_Name
和 Guest_Telephone
.
之间有函数依赖
你可以记住:
如果关系是第二范式,并且键中只有一个附加属性,那么它自动是第三范式。
在您的示例中,您可以简单地将属性名称 Guest_Name
修改为 Reservation_Description
,冗余指示将不再那么明显。
也尝试将Guest_Name
拆分为Guest_Firstname
和Guest_Lastname
两个属性,会发生什么?
仅指示冗余并不意味着您使用前 3 个正常形式之一,但正如您所说的正确,最好将预订和客人分开。
最后要提的一件事
您的属性 Guest_Name
可以被视为一个 键,没有要求键必须是数字。考虑一下您的酒店(或您预订 table 的目的)容纳 "numbers" 而不是人(好吧,我希望您有强大的想象力...)。拥有这样的架构是否有意义:
Reservation_PK Guest_FK
1 1
2 2
3 1
Guest_PK Guest_Name
1 34
2 57
当然不是,您可以将 Guest_Name
留在原处:
Reservation_PK Guest_Name
1 34
2 57
3 34
因此,如果您不想保存除客人姓名以外的任何其他属性,我会保留您的预订 table 原样(它甚至完全满足普通表格 3 的所有要求).
假设以下 "Reservations" table 有两列 Reservation_Number 和 Guest_Name。 Reservation_Number 是唯一的候选键:
Reservation_Number Guest_Name
------------------ ------------
1 john smith
2 john smith
3 john smith
4 jane doe
5 bob anderson
我的问题是这个 table 是否符合第三范式?
- 好像没有违反第一范式。当 table 具有主键并且每个属性的域仅包含原子值,并且每个属性的值仅包含来自该域的单个值时,它处于 1NF 中。在此示例中,Reservation_Number 是主键,并且 Reservation_Number 和 Guest_Name 都满足原子条件。
- 好像没有违反第二范式。当 table 在 1NF 中时,它在 2NF 中,并且 table 的每个非主要属性都依赖于每个候选键的整体。 Guest_Name 是唯一的非主属性,它完全依赖于唯一的候选键,即 Reservation_Number。
- 好像没有违反第三范式。当 table 处于 2NF 时,它处于 3NF,并且 table 的每个非素数属性都非传递地依赖于 table 的每个超键。唯一的非主属性 Guest_Name 非传递地依赖于唯一的超级键,即 Reservation_Number。
然而,这里有冗余table。我知道我可以通过以下方式删除这些冗余:
a) 使用 Guest_Id 和 Guest_Name 列创建访客 table。
b) 将预订 table 中的 Guest_Name 替换为 Guest_Id FK。
但我的问题是,原始预订 table 怎么可能是第三范式,但在 Guest_Name 列中却有冗余?如果它违反了正常形式,那么如何以及为什么?请帮忙!
您的示例不会违反第二和第三范式,但是如果您添加一列 Guest_Telephone
会怎么样。那么第三范式就会被违反,因为你在 Guest_Name
和 Guest_Telephone
.
你可以记住:
如果关系是第二范式,并且键中只有一个附加属性,那么它自动是第三范式。
在您的示例中,您可以简单地将属性名称 Guest_Name
修改为 Reservation_Description
,冗余指示将不再那么明显。
也尝试将Guest_Name
拆分为Guest_Firstname
和Guest_Lastname
两个属性,会发生什么?
仅指示冗余并不意味着您使用前 3 个正常形式之一,但正如您所说的正确,最好将预订和客人分开。
最后要提的一件事
您的属性 Guest_Name
可以被视为一个 键,没有要求键必须是数字。考虑一下您的酒店(或您预订 table 的目的)容纳 "numbers" 而不是人(好吧,我希望您有强大的想象力...)。拥有这样的架构是否有意义:
Reservation_PK Guest_FK
1 1
2 2
3 1
Guest_PK Guest_Name
1 34
2 57
当然不是,您可以将 Guest_Name
留在原处:
Reservation_PK Guest_Name
1 34
2 57
3 34
因此,如果您不想保存除客人姓名以外的任何其他属性,我会保留您的预订 table 原样(它甚至完全满足普通表格 3 的所有要求).