在你有多个表格的情况下很常见,比方说Posts
,Entries
和News
,用户可以对其中任何一个进行评论。
认为这样的自然方式会是这样的:
但是,使用parent_type
属性设置主键对我来说似乎不明确,因为它并没有真正描述注释所属的父。
在我看来,理解关系的最明确方式是为每个关系创建一个中间表:posts_comments
,posts_entries
,posts_news
。但是,在数据库设计方面,这并没有多大意义,因为您不需要one to many
关系的中间表,只有many to many
关系才需要它们。
然后,第三种方法可能是根据它所属的内容制作不同的Comment
模型:PostComment
,EntryComment
。这将有助于更好地理解该评论的用途,但我认为这是一个糟糕的想法,因为评论可以只用一个表来表示,你最终可能会得到一堆不同的表,并且可能只是由一张桌子代表。
那么,这种情况的常用方法是什么?
答案 0 :(得分:1)
我同意你不想创建三个几乎相同的表,如果你能提供帮助的话。我已经看到很多数据库都是这样做的,而且很痛苦,因为任何变化都可能会影响所有的变化,所以你必须做三次而不是一次更改,有三次许多要改变的查询。迟早有人会做出改变而不知道他应该对其他两张桌子做出同样的改变,或者匆忙或忘记,然后六个月后其他人出现并想知道是否有原因这三张桌子略有不同,或者只是粗心大意。
但是你也不想要一个含糊不清的专栏。您根本不需要可以根据类型字段的内容引用不同表的外键。那真是太丑了。
我曾经使用的类似问题的解决方案是创建一个中间表。在这种情况下,它将是 - 我不知道你是否有一个包含新闻,帖子和事件的单词,所以让我把它们全部统称为#34;文章"。所以我们创建了一个article_comments表。除ID外,它可能没有数据。然后新闻,帖子和事件都有指向article_comments的指针,注释有一个指向article_comments的指针。
因此,如果你想要给定新闻记录的所有评论,那就是:
select whatever
from news n
join article_comments ac on ac.iarticle_comments_id=n.article_comments_id
join comments c on c.article_comments_id=ac.article_comments_id
where n.news_id=@nid
请注意,使用此结构,所有FK都是单个表的真实FK。你没有让article_comments指向新闻,帖子和事件;你把新闻,帖子和事件指向了article_comments,所以所有的FK都是干净的。
是的,它是一个额外的表来读取,这会慢慢减慢查询速度。但我认为保持FK清洁是值得付出的代价。
如果你不知道文章的类型,如果你想知道给定评论是针对哪一篇文章,那么这个结构的一个公认的笨拙查询就是这样。那必须是:
select whatever
from comment c
join article_comment ac on ac.article_comment_id=c.article_comment_id
left join news n on n.article_comment_id=ac.article_comment_id
left join post p on p.article_comment_id=ac.article_comment_id
left join event e on e.article_comment_id=ac.article_comment_id
where c.comment_id=@cid
然后查看哪些新闻,帖子和事件非空。 (你也可以通过加入一个属于联盟的子查询来实现它,但我认为那会更加丑陋。)
答案 1 :(得分:0)
等一下。但是,您可以按照以下方式设计模型:
#Entity
#评论:
其他方式(仅一张桌子)
希望对任何人都有用!