一对多数据库关系

时间:2011-04-06 16:18:25

标签: database database-design normalization

伙计我真的很感激,如果有人可以帮助我。我有一个模式与4个表相关的这个问题书籍,组,阅读列表,评论。系统的用户可以加入组并将书籍添加到该组的阅读列表中。组的书列表由表ReadingList表示:

ReadingList
-------------
Id (auto_increment)
ReadingListID
BookID (pk)
GroupID (pk)

BookID和GroupID被设置为复合主键,以确保任何书籍都不会出现在组阅读列表上两次。这两个字段都有一个fk定义到相关表Books / Groups。现在我的问题出现在试图建立Comments表和ReadingList之间的关系时。理论上,ReadingList中的每个唯一条目都可以有很多注释(1 .. *),因此基本上一组阅读列表上的书可以有很多与之相关的注释.Reviews表看起来像这样:

Comments
-----------
Id (pk, auto_increment)
ReadingListID
UserName
Comment
TimeStamp

我的逻辑是将一个fk从Comments(ReadingListID)设置为ReadingList(ReadingListID),但是我明显存在缺陷,因为我在“引用表中没有主键或候选键”错误。

我尝试过各种各样的东西,比如制作ReadingListID&在Comment表中的Id是一个复合键,并使ReadingListID成为ReadingList表中的一个pk等,但我无法理解这一点。如果我不够清楚,请告诉我。

非常感谢!

4 个答案:

答案 0 :(得分:3)

enter image description here

每个BookInGroupCommentNo组合的integerGroupID, BookID,序列号(1,2,3 ..)。使用

创建新评论时可以轻松获得
select
    coalesce(max(BookInGroupCommentNo), 0) + 1  
from ReadingList
where GroupID = some_group_id
  and BookID  = some_book_id ;

IDsReadingListID表中删除那些自动增加ReadingListComment的内容。

答案 1 :(得分:2)

你可以做的是使用从复合(BookID + GroupID)到ReadingListID列的ReadingList的主键,然后你的FK将工作。然后,您可以跨BookID + GroupID列创建唯一约束或索引,以强制实施数据完整性。

我很困惑,为什么你在ReadingList(Id)上有一个自动增量,它与你的ReadingListID列分开。也许你应该放弃一个或另一个。在我看来,你的架构似乎是如何设置的,也许是ReadingList.Id是PK,而Comments.ReadingListID是该列的FK。

答案 2 :(得分:1)

那是因为ReadingList的主键实际上是一个复合键(BookID,GroupID)。您应该更新您的评论表并拥有BookID和GroupID而不是ReadingListID。

为什么你有ReadingListID?您不需要它,因为您已经定义了复合主键。

答案 3 :(得分:1)

我建议:

ReadingList
-------------
ReadingListID (pk, auto_increment)
BookID (fk)
GroupID (fk)
+ Unique index on (BookID, GroupID)

Comments
-----------
CommentID (pk, auto_increment)
ReadingListID
UserName
Comment (maybe "Content", "Value" or "Body" could help avoid typing comments.comment)
TimeStamp