在构建一个ASP论坛或消息板时,面临着如何有效地展示相关话题的挑战。通常,需要将所有相关的消息以层次结构的形式展示出来,以便用户能够清晰地看到消息之间的关联。本文将探讨如何通过优化SQL结构来实现这一目标,以及如何提高论坛的性能和可扩展性。
想象一下,在一个新闻组中,人们发布问题,其他人回复。显然,需要格式化消息,使得所有与同一主题相关的消息都显示在一起。这是通过层次结构来实现的,所以第一个消息出现在层次结构的顶部,应该首先阅读。论坛或消息板的工作原理完全相同。那么,如何通过SQL结构如表、字段、关系等来表达这一点呢?
让看一下下面的图片(图1),展示了一个简单的论坛或基于Web的消息板可能如何在SQL结构中表达。From、Subject、Text和Date字段是自解释的。层次结构由主键Id给出,它唯一地标识主题,以及外键Id_parent,它们之间的关系如图片所示。简而言之,一个主题Id=X将有所有Id_parent=X的回复作为其回复。这很简单。但为什么说它是简单的呢?
让看看将如何展示这种层次结构...首先,将选择所有没有父级的主题,即最上层级,然后对于每个主题,将选择所有以这个主题为父级的主题,然后对于每个子主题,将选择...,然后对于每个...,等等。这并不容易,对吧?如果以前玩过游标,会知道可以做一些改进,但仍然会有一个繁琐的任务,大量的处理,也许在繁忙的服务器上会导致数据库服务器拥堵。这绝对不是一个可扩展的解决方案。忘了它...
在性能和可扩展性方面,最好的软件解决方案不是通用解决方案,而是针对性的解决方案。为了针对性地解决问题,让分析一下问题。在论坛解决方案中,用户将从数据库中写入和读取。从统计学上讲,写入将占1-20%,而读取将占其余部分。所以,希望读取过程尽可能快,并将负担从读取转移到写入,后者的使用频率远低于读取。理想情况下,希望一个SELECT就足够了,而写入过程可能会变得更复杂,需要多个SELECT和INSERT。
增加了两个字段:DisplayOrder和DisplayDepth。这个想法很简单。DisplayOrder和DisplayDepth将允许按显示顺序SELECT项目,如图3所示。
DisplayOrder简单地保持项目的显示顺序,而DisplayDepth保持层次深度,这将帮助显示层次结构。所以,现在可以简单地:
SELECT * FROM Topics ORDER BY DisplayOrder
然后使用游标根据DisplayDepth进行显示。是的,猜对了,DisplayOrder和DisplayDepth是在写入时计算的。所以,在写入时,知道Id_parent=X(当前要插入的主题的父级),发生的事情是:
SELECT DisplayOrder as Y, DisplayDepth as Z FROM Topics WHERE id=X
INSERT INTO Topics (...,DisplayOrder, DisplayDepth, Id_parent, ...) VALUES (...,Y+1, Z+1, X,...)