浅谈wiki的设计

    虽然网上现成的wiki一大票,不过对需要进行定制开发的时候这些wiki就未必适合了。由于只是想整个最基本的wiki功能,因此打算自己整一整。 也许是有些厌倦了java,也许是想更深入的体会一下脚本语言的魅力,我决定采用django来进行开发。而且使用django有个好处,支持python的虚拟主机比支持java的好找。
    虽然是重新开始整,但如果有现成的轮子当然是最好了。既然决定使用django,当然要到django的code目录去找找。diamanda,一个论坛+wiki的程序。功能很简单,但作为一个轮子还是一个不错的选择。wiki最大的特色就是版本控制,因此我对wiki的版本控制算法比较关心。看了一下版本控制部分,居然是每个版本都全部保存(我一直认为wiki应当是增量保存的)。这意味着即使是一个很小的改动也得重新保存一份。对于一篇很长的文章来说,冗余实在是大得惊人。想来也许是这个程序的问题,于是考虑去找些其他的wiki程序作为参考。除去django的项目,其他的python wiki项目也不错。反正算法什么的都可以直接用。(中途还down了个java的wiki,不过没耐心看)
    又去溜达了一圈,看中了moin,python里最知名的wiki项目之一。不熟悉moin的web处理模型,看得我似懂非懂。不过基本上可以确定,他也是每个版本保存一份。
    最后想想还是去看看mediawiki吧,世界上最大的wiki“基维”用的就是他。有些晕,这个也是使用全部保存的方式。想来“基维”有好几百w的数据,加上每条纪录都有多个版本,“基维”的数据库压力定是N大。不过到此我也不用去想搞啥增量算法了。众多wiki程序都是使用的全部保存模式,定是有些道理。增量算法即使有,也必定会有不少难点有待解决。
    下面看看mediawikiwiki的设计吧。
    mediawiki使用数据库来存储wiki数据。一张page信息表用于保存每个wiki页面的信息。可能是考虑到性能问题,真正的页面内容却没有保存在该表中,而是单独保存在text表中。表里的数据都是以blod方式保存,为什么这样做俺就不太清楚了,难道是效率更高?只有最新版本的数据才是需要索引的数据,因此单独出一张索引表,用来进行索引查询。文本内容在被索引前实现要进行一次过滤,过滤掉wiki标签等。
    由于加入了版本控制,数据库中数据表中的纪录数将是实际主题的好几倍。而且随着wiki内容的丰富和完善,数据库中纪录大小将迅速膨胀。数据库的压力不言而喻。
    为了减轻数据库的压力,有些wiki选用使用了更高效的办法,使用文件的形式存储wiki内容。其中moin就是这样做的。moin使用一定的规则将wiki纪录以文件的形式保存,并使用lupy(1)对文件进行索引,提供查询的支持。
    为了减少每个版本都全部保存一遍所带来的巨大冗余,不少wiki都支持分段编辑。即可以对每段进行单独的编辑,在保存的时候只保存做修改那部分的内容。

(1)lupy 一个lucene的python移植版。与pylucene使用gcj移植不同的是,lupy完全使用python对lucene改写。lupy的问题是支持lucene版本比较低,只支持到1.2。