[我不是在询问SO的架构,但这对问题有帮助。]
在SO上,当用户点击他/她的名字并点击“回复”时,他们会看到其他用户对他们参与的评论主题,问题和答案的回复。我有一种潜在的怀疑,我错过了某些回复,这让我想知道:如果你必须构建那个东西,你会在每次用户请求的时候从数据库中动态提取所有内容吗?或者当应用程序中有新的相关活动时,您会修改它吗?或者你会在夜间守护进程中构建它吗?
我认为真正的答案是它每次都是动态构造的,但是这些表是以这样的方式非规范化的,这样可以减少耗时的事情。 你会如何构建它?
我问的是任何平台,当然,不仅仅是.Net。
答案 0 :(得分:5)
我每次都会从数据库中动态提取它。我认为这可以从用户体验中获得最佳结果,然后我会应用过早优化是邪恶的原则。稍后如果出现性能问题,我会考虑缓存。
我认为将其作为守护进程/推送进程实际上会导致更多的整体工作。也就是说,更新会比用户请求信息更频繁地发生。
答案 1 :(得分:1)
显然,当发布回答或评论时,您需要确定应在其回复标签中通知的用户。然后只需在响应表中添加一行,其中包含响应文本,时间戳和它所属的用户。这样,您可以使用简单的
动态生成选项卡select * from responses where user=<userid> order by time desc limit 30
或类似的东西。
p.s。对可以编写将删除旧回复的查询的任何人的额外信用 - 假设每个人的回复标签中应该有最后30个回复。
答案 2 :(得分:1)
我希望userid是聚簇索引的自然选择。如果你有一个“Active”布尔字段,那么你不需要担心锁;除了更新(未编制索引的)活动列外,该表可以是只写的。我打赌它已经这样运作了,因为看起来一切都是可以恢复的。
不需要任何臭味的额外信用回复卸妆。
答案 3 :(得分:1)
我认为这在数据库中是非规范化的。 Comment表可能同时包含了answer_id和answer_uid,因此只需对注释表运行就可以找到对你的回答的SQL的SQL。相同的设置可以在答案表上使用。每个答案都有一个question_id和一个question_uid。
话虽如此,这些可能是同一个表,你有response_to_id和response_to_uid,这使得大量代码更简单,并使“最近”选项卡也成为一个选择。事实上,两个选择之间的区别是一个使用uid,一个使用response_to_uid。
答案 4 :(得分:1)
我要说你的用户界面和你的数据库都应该由你的应用程序域驱动;所以他们会根据他们在那里的共同起源相互反映。
使用Fowler等人讨论的简化对象角色建模来说明一些快速说明。
实体
用户
问题
答案
评论
实体角色
(注意:在对象角色建模中,大多数角色都是反身的。有些人,例如这里的布尔,是单极的)
问题有用户
问题有QuestionVersions
问题作为答案
问题有评论
答案有AnswerVersions
答案有评论
问题有用户
QuestionVersion有文字
QuestionVersion有时间戳
QuestionVersion有IsDeleted(可以从nonNULL时间戳推断出来)例如
QuestionVersion有DeltedByUser
QuestionVersion有DeletedTimestamp
答案有用户
AnswerVersion有文字
AnswerVersion有时间戳
AnswerVersion有IsDeleted
AnswerVersion有DeltedByUser
AnswerVersion有DeletedTimestamp
评论有文字
评论有用户
评论有时间戳
注释IsDeleted(boolean)
(注意 - 评论没有版本)
我认为这是基础知识。这些断言驱动ORM中的ERD。希望他们如何推动用户故事也是不言而喻的。
我认为像这样的规范化设计的实现不需要非规范化 - 特别是因为我认为(从行为上)查询=&gt; UI显示被缓存以每分钟刷新1次。