代码之家  ›  专栏  ›  技术社区  ›  ANaimi

高性能wiki模式

  •  0
  • ANaimi  · 技术社区  · 15 年前

    对于类似Wiki的系统,最好的模式是什么?用户编辑/修订提交文件,系统跟踪这些提交文件。

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

    我当前的模式(我知道它不好)使用一个表。当我需要查看“最新提交”时,我会按“LatestActivity”排序,按“DocumentTitle”分组,然后取前N条记录。我认为很多分组(特别是在nvarchar上分组)都是坏消息。为了列出浏览次数最多的记录,我也做了同样的操作:按视图排序、按名称分组、获取前N条记录。大多数时候,我也会做一个“WHERE DocumentName,比如“%QUERY-HERE%”。

    我当前的模式是“版本1”,请参见以下内容: alt text http://www.anaimi.com/junk/schemaquestion.png

    我认为这是不可接受的。因此,我正试图提出另一个/更高性能的设计。你觉得第二版怎么样?在第二版中,我得到了在WikiHeadId上分组的优势,WikiHeadId是一个数字——我假设在一个数字上分组比在nvarchar上分组更好。

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

    此类系统是否有更好的/已知的模式?

    谢谢

    2 回复  |  直到 15 年前
        1
  •  2
  •   Cowan    15 年前

    首先(出于好奇)当前模式如何指示当前版本?您是否有多个具有相同文档标题的“WikiDocument”条目?

    Wiki中的“版本”只写一次:如果你修改了一个版本,那么你就是在创建一个新版本 刚出现的

    实际上,你设计的“自然”模式是#2。就我个人而言,我有点喜欢旧的DB公理“规范化,直到它受伤,然后去规范化,直到它工作”#2是一个更干净、更好的设计(简单,没有重复),如果你没有迫切的理由去规范化到版本3,我就不麻烦了。

    归根结底,归结到这一点:您是因为观察到性能问题而担心“更高性能”的设计,还是因为您假设 吃点吗?没有真正的理由,2号不应该表现出色。在SQL Server中,分组并不一定是坏消息——事实上,如果查询有一个合适的覆盖索引,它可以执行得非常好,因为它可以导航到索引中的某个特定级别以查找分组的值,然后使用索引的剩余列来使用最小/最大/任何值。按NVARCHAR进行分组并不特别糟糕——如果没有发现这是一个问题,不要担心,尽管(非二进制)排序规则可能会让它变得有点棘手——但在版本2中,您需要按WikiHeadId进行分组,可以按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)
    ...
    

    这两个都很讨厌。如果WikiHead保留一个指向当前版本的指针,它只是

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

    或者不管怎样,这可能是一个有用的非规范化,只是因为它使您的生活更轻松,而不是为了性能。

        2
  •  0
  •   Sam    15 年前

    检查 this 出来

    它是的数据库模式 mediawiki ,这是维基百科的基础。

    由此 page