如何在1NF中建模可选的一对多关系

时间:2009-07-23 12:55:21

标签: database-design

如何在不破坏第一个普通形式的情况下建模零,一个或多个类型关系?也就是说,不存储任何NULL值。

单独的关系表?是否“值得”添加表格,还是这种过度规范化?

这是一个与我的真实案例相对应的例子:

假设我们有一所大学,有一些免费课程和一些免费宿舍。部分课程和宿舍房间收费。许多课程和房间都有相同的费用(金额),虽然它们是不同的课程/房间。

所以我们会:

tblCourse
Id
Name

tblDormRoom
Id
Address

tblFee
Id
Amount

为了对此进行建模,我的目的是添加两个表以保持可选的一对多关系。

tblCourseToFee
CourseId
FeeId

tblDormRoomToFee
DormRoomId
FeeId

这样我可以避免存储任何空值,并且还可以避免在DormRoom和课程之间共享费用的重复存储。

考虑到快速且更脏的版本,并不严格遵守1NF:

tblFee
Id
CourseId (nullable)
DormRoomId (nullable)
Amount

这只使用一个表而不是三个,但引入了空值..

3 个答案:

答案 0 :(得分:2)

这是一个有趣的问题 - 可以找到第一范式中一对多关系的一个很好的例子on Wikipedia(我想在这里发布一些内容,但它不是Stackoverflow-格式友好)。

基本思想是定义两个表,主表的标识符用作相关表的标识符,并理解相关表可能包含重复的标识符。

好奇心问题是你在从事某种数据挖掘项目吗?我有兴趣了解更多关于如何应用这一点的信息。

答案 1 :(得分:1)

请参阅安德鲁与维基百科的链接,并注意到按日期排名的“1NF中的无效空格”最多只是具有争议性 - 更不用说经常不切实际了。如果Cod的空值足够好,那么它们对我来说已经足够了;-)

<小时/> 也就是说,建立零,一或多种关系的正常(双关语)方式是使用子表,例如

create table Parent (
    Id int not null identity(1),
    Somefield nvarchar(256) not null,
    ...
)

create table Child (
    Id int not null identity(1),
    ParentId int not null,    --foreign key to Parent table's Id
    AnotherField nvarchar(128) not null
    ...
)

答案 2 :(得分:0)

从语义上看这个问题。它是三元关系还是两个二元关系?简单来说: 是收取的费用

  • 课程
  • for a dorm
  • 用于住宿的宿舍 参加课程

    对于前两种情况,您需要有两个子表。如果情况三是真的,你需要在课程,费用和宿舍之间只有一个交叉表。 很多时候,NULL的存在与否都与微妙的设计问题密切相关。
相关问题