优化分层 SQL 结构(ASP 方法)





5.00/5 (3投票s)
2001 年 10 月 16 日
4分钟阅读

106686

663
一篇关于如何改进 SQL 分层结构的 #-}的文章。
引言
这篇文章花哨的标题可以改写成:如何编写一个ASP论坛或如何改进你的ASP公告板。我敢打赌,这个标题会更有商业吸引力。然而,这更像是一个SQL优化问题,而ASP论坛示例只是一个实际的案例。但是,正如我们将看到的,我们的文章并非高度理论化,而是面向问题的解决。
问题所在
想象一个新闻组,人们发布问题,其他人回复。显然,你需要格式化消息,以便所有与同一主题相关的消息一起显示。这是通过分层方式完成的,因此第一条消息首先出现在层次结构中,下划线表示应首先阅读。论坛或留言板的工作方式完全相同。所以让我们看看如何通过SQL结构(如表、字段、关系等)来表达这一点。
一种幼稚的方法
看看下面的图片(图1),它显示了如何在SQL结构中表达简单论坛或基于Web的留言板的简单表格。
“发件人”、“主题”、“文本”和“日期”字段不言自明。层次结构由主键Id给出,它唯一地标识主题,并由外键Id_parent
给出,外键参与如图所示的关系。简而言之,Id=X
的主题将所有Id_parent=X
的主题作为回复。非常简单明了。为什么它很幼稚呢?
让我们看看我们将如何显示这个层次结构……首先,我们将SELECT
所有没有父级的主题,即上层,然后对于每个主题,我们将SELECT
所有具有此主题作为父级的主题,然后对于每个子主题,我们将SELECT
……,然后对于每个……等等。是不是不太容易?如果你以前使用过游标,你会知道可以做一些改进,但我们仍然会有一个繁琐的任务,大量的处理,并且在繁忙的服务器上可能会导致数据库服务器拥塞。这绝对不是一个可扩展的解决方案。忘了它吧……
一种更智能的统计方法
就性能和可扩展性而言,最好的软件解决方案不是通用解决方案,而是有针对性的解决方案。为了针对我们的解决方案,让我们分析一下问题。在论坛解决方案中,用户将写入和读取数据库。从统计上看,写入将占1-20%,而读取将占其余部分。因此,与其像之前的解决方案那样将负担放在读取上,不如将读取过程的速度尽可能加快,并将负担从读取转移到写入,而写入远不如读取常用。理想情况下,我们希望只需要一个SELECT
就足够了,而写入过程可能会变得更复杂,需要多个SELECT
和INSERT
。看看下一张图片(图2)。
我们添加了两个字段:DisplayOrder
和DisplayDepth
。嗯,这个想法很简单。DisplayOrder
和DisplayDepth
将允许我们按照图3所示的精确显示顺序SELECT
项目。
如你所见,DisplayOrder
只是保持项目的显示顺序,而DisplayDepth
保持层次结构的深度,这将帮助我们显示层次结构。因此,现在我们可以简单地
SELECT * from Topics ORDER BY DisplayOrder
然后用游标根据DisplayDepth
缩进显示。是的,你猜对了,DisplayOrder
和DisplayDepth
是在写入时计算的。因此,在写入时,知道Id_parent=X
(要插入的当前主题的父级),将会发生以下情况:
'find the parent
SELECT DisplayOrder as Y, DisplayDepth as Z FROM Topics WHERE id=X
'insert the new topic and update DisplayOrder and DisplayDepth
UPDATE Replies SET DisplayOrder=DisplayOrder+1 WHERE DisplayOrder>Y
INSERT INTO Topics (...,DisplayOrder, DisplayDepth, Id_parent, ...) VALUES (...,Y+1, Z+1, X,...)
简单来说:我们确定父级的DisplayOrder
。新的回复主题的DisplayOrder
将等于父级的DisplayOrder + 1
。但首先,我们必须确保没有其他项目具有此DisplayOrder
,因此我们只需将所有应在要插入的项目之后显示的项目的DisplayOrder
加1。要更详细地了解这里发生了什么,请研究附加到本文的演示示例,然后尝试编写自己的示例。
结论
在处理后端数据库服务器时,可以进行许多改进,这些改进将极大地影响应用程序的可扩展性。如果你同时实现幼稚的方法和更智能的统计方法,你将看到区别。绝对值得考虑这样的改进。演示示例中提供了一个ASP实现。我在我的网站上自己使用了这项技术,以便人们可以对我的文章进行分层反馈。