【发布时间】:2008-11-28 02:01:45
【问题描述】:
我正在开发一个社交网络系统,该系统将拥有来自多个不同位置的 cmets。一个可以是朋友,一个可以是事件,一个可以是群组——很像 Facebook。我想知道的是,从实际的角度来看,编写 cmets 表的最简单方法是什么?我应该在一个表中完成所有操作并允许外键访问各种不同的表,还是每个不同的表都有自己的注释表?感谢您的帮助!
【问题讨论】:
我正在开发一个社交网络系统,该系统将拥有来自多个不同位置的 cmets。一个可以是朋友,一个可以是事件,一个可以是群组——很像 Facebook。我想知道的是,从实际的角度来看,编写 cmets 表的最简单方法是什么?我应该在一个表中完成所有操作并允许外键访问各种不同的表,还是每个不同的表都有自己的注释表?感谢您的帮助!
【问题讨论】:
我认为单 cmets 表是更优雅的设计。不过,不要考虑多个 FK,而是考虑一个中间表 - CommentedItem。因此,Friend、Event、Group 等都具有 CommentedItem 的 FK,并且您为每个表中的每个新行创建一个 CommentedItem 行。现在 Comments 只需要一个 FK 到 CommentedItem。例如,要获取给定朋友的所有评论:
SELECT * FROM Comment c
JOIN CommentedItem ci on c.CommentedItemId = ci.CommentedItemId
JOIN Friend f on f.CommentedItemId = ci.CommentedItemId
WHERE f.FriendId = @FriendId
【讨论】:
我都做过,答案取决于具体情况。对于你想要做的事情,我会做一个“评论”表,然后单独的“链接器”表。这将为您提供最佳性能,因为您可以实现“Perfect Index”。
我还建议在 Comments 表中放置一个“CommentTypeID”字段,以提供有关您将从哪个链接器表中提取附加详细信息的“线索”。
编辑:CommentTypeID 字段不应在索引中使用,而只能在代码中使用。
【讨论】:
需要注意的一点是,如果您不使用高度规范化的数据库,它有时会导致 IO 行链接和表扫描。
我相信 oracle 建议执行大约第三范式的规范化模型。
【讨论】:
这是与this one 相同的问题。
编辑:根据评论,尚不清楚这是一个等效问题,因此我在下面将其拼写出来。
这两个问题都询问有关数据库性能问题的项目(两者都恰好是社交网络,但这只是巧合)。两者都有一组不同的对象,它们共享一个共同的属性集合(一个是事件,发生在每个对象上,另一个是发生在每个对象上的注释)。
这两个问题都有效地询问了创建一个结合不同的共同特征的 UNION 查询,或者使用适当的外键将它们分解到一个公用表中是否更有效。
我认为它们是等价的;对一个的最佳答案将同样适用于另一个。
(如果您不同意,我很高兴听到原因;请发表评论。)
【讨论】:
我会选择polymorphic associations。许多现代 Web 开发框架开箱即用地支持它,这使其成为处理此类关系的最简单、最轻松的方式。
【讨论】:
其实你可以去http://www.zazazine.com看看他们的文章。你可以在那里找到答案
【讨论】: