高性能wiki架构

时间:2009-07-10 20:38:32

标签: sql-server performance high-availability

我正在使用MS SQL Server 2005。

类似Wiki的系统的最佳架构是什么?用户编辑/修改提交的位置,系统会跟踪这些提交。

让我们说我们正在做一个简单的基于wiki的系统。将跟踪每个修订版本以及每个修订版本的最新活动。在其他屏幕中,系统将列出“最新提交”和“观看次数最多”,以及按标题搜索。

我当前的架构(我知道它很糟糕)正在使用单个表。当我需要查看“最新提交”时,我按“LatestActivity”排序,按“DocumentTitle”分组,然后取前N个记录。我假设很多分组(特别是在nvarchar上分组)是坏消息。对于列出查看次数最多的我也做同样的事情:按视图排序,按名称分组,取前N条记录。大多数时候,我也会做一个“WHERE DocumentName LIKE'%QUERY-HERE%'”。

我当前的架构是“版本1”,见下文: alt text http://www.anaimi.com/junk/schemaquestion.png

我认为这是不可接受的。所以我试图想出另一个/更高性能的设计。版本2对你有什么影响?在第二版中,我获得了对WikiHeadId进行分组的优势,这是一个数字 - 我假设分组数量比nvarchar更好。

或者是版本3的极端情况,我不进行分组,但有一些缺点,例如复制值,在代码中维护这些值等等。

此类系统是否有更好/已知的架构?

感谢。

(从ServerFault转移 - 我认为它不仅仅是一个IT问题,而是一个开发问题)

2 个答案:

答案 0 :(得分:2)

首先(出于好奇心)当前架构如何表明当前版本是什么?您是否只有多个具有相同DocumentTitle的“WikiDocument”条目?

我也不清楚为什么你需要版本级别的'LastActivity'。我不知道'LastActivity'如何适应'版本'的概念 - 在大多数 wiki中,'版本'是一次写入:如果你修改版本,那么你就是创建 new 版本,因此版本上最后更新的类型值的概念毫无意义 - 它实际上只是'datecreated'。

真的,你设计的'自然'架构是#2。就个人而言,我有点喜欢旧的数据库公理'正常化,直到它受到伤害,然后反规范直到它起作用'。 #2是一个更干净,更好的设计(简单,没有重复),如果你没有迫切的理由反规范到版本3,我不会打扰。

最终,它归结为:你是否担心“更高性能”的设计,因为你已经观察到性能问题,或者因为你假设可能有一些?没有真正的理由#2不能表现良好。分组在SQL Server中不一定是坏消息 - 实际上,如果查询有适当的覆盖索引,它可以执行得非常好,因为它只能导航到索引中的特定级别以查找分组值,然后使用要使用的其余列的MIN / MAX /无论如何。 NVARCHAR的分组并不是特别糟糕 - 如果没有观察到它是一个问题,不要担心它,虽然(非二进制)排序可以使它有点棘手 - 但在版本2中,你需要GROUP BY你可以通过WikiHeadId做到,对吧?

有一件事可能会让生活更轻松,如果你对当前版本进行大量操作(我认为你会这样做),可以将FK从head表添加回body表,指示当前版本。如果你想查看点击次数最多的当前版本,那么#2现在可能是:

SELECT TOP ...
FROM WikiHead
INNER JOIN 
  (SELECT WikiHeadId, MAX(WikiBodyVersion) /* or LastUpdated? */ AS Latest 
   FROM WikiBody GROUP BY WikiHeadId) AS LatestVersions
INNER JOIN WikiBody ON 
  (Latest.WikiHeadId = WikiBody.WikiHeadId)
  AND (WikiBody.WikiBodyVersion = LatestVersions.Latest)
ORDER BY 
  Views DESC

或者

...
INNER JOIN WikiBody ON 
  (WikiHead.WikiHeadId = WikiBody.WikiHeadId)
  AND (WikiBody.WikiBodyVersion = 
    (SELECT MAX(WikiBodyVersion) FROM WikiBody WHERE WikiBody.WikiHeadId = WikiHead.WikiHeadId)
...

两者都是icky。如果WikiHead保留了指向当前版本的指针,那么它只是

...    
INNER JOIN WikiBody ON 
  (WikiHead.WikiHeadId = WikiBody.WikiHeadId)
  AND (WikiHead.Latest = WikiBody.WikiBodyVersion)
...

或其他什么,这可能是一个有用的非规范化,只是因为它让你的生活更轻松,而不是为了表现。

答案 1 :(得分:0)

检查this

这是维基百科所基于的mediawiki的数据库架构。

它看起来很好记录,对你来说是一个有趣的读物。

来自page