直接从数据库或缓存生成网页?

时间:2009-01-09 19:51:18

标签: optimization architecture

[我不是在询问SO的架构,但这对问题有帮助。]

在SO上,当用户点击他/她的名字并点击“回复”时,他们会看到其他用户对他们参与的评论主题,问题和答案的回复。我有一种潜在的怀疑,我错过了某些回复,这让我想知道:如果你必须构建那个东西,你会在每次用户请求的时候从数据库中动态提取所有内容吗?或者当应用程序中有新的相关活动时,您会修改它吗?或者你会在夜间守护进程中构建它吗?

我认为真正的答案是它每次都是动态构造的,但是这些表是以这样的方式非规范化的,这样可以减少耗时的事情。 你会如何构建它?

我问的是任何平台,当然,不仅仅是.Net。

5 个答案:

答案 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次。