自建明文Wiki(数据库内的Wiki)

6

有没有人知道一个API(最好是PHP,但我对任何语言都感兴趣)用于创建类似维基百科的数据存储?

还有没有关于自己制作纯文本维基的资源?其他纯文本维基如何处理文本文件的格式?

我知道可以使用Markdown或Textile进行格式化。但我最感兴趣的是如何处理多用户编辑的纯文本存储。

我正在编写一个主要基于数据库驱动的Web应用程序。我希望数据库中至少有一个文本字段以维基百科的格式存在。具体来说,此文本可以由多个用户编辑,并能够回滚到任何版本。想象一下Last.FM的维基/个人简介部分(除了这个部分,整个站点都是严格由数据库结构化的)。

到目前为止,我从MediaWiki中拆解并将其插入数据库的方法似乎有些大材小用。我认为自己制作纯文本维基并将其存储在数据库的适当文本字段中会更容易。


你无法向数据库添加新表格或者其他什么吗?我不明白为什么你想在数据库中创建一个“明文”维基。也许是我没有理解你的术语。 - Chad Birch
我想在我的数据库中将一个单一的维基页面存储在一个文本字段中。 - ack
不清楚你的问题的答案是“MySQL有一个用于大型数据的文本数据类型”,还是你正在询问更复杂的版本控制等内容。 - Dan Rosenstark
哦不,我正在寻找维基风格的版本控制。我想通过将数据存储在数据库文本字段中的纯文本维基语法中来实现这一点。 - ack
4个回答

15

基本上这是一个“如何在我的数据库中对文本信息进行版本控制”的问题。

那么,最简单的方法就是简单地复制数据。

简单地创建一个“版本”表来保存数据的“旧版本”,并将其链接回主表即可。

create table docs {
    id integer primary key not null,
    version integer not null,
    create_date date,
    change_date date,
    create_user_id integer not null references users(id),
    change_user_id integer references users(id),
    text_data text
}

create table versions {
    id integer primary key not null,
    doc_id integer not null references docs(id),
    version integer,
    change_date date,
    change_user integer not null references users(id),
    text_data text
}

每当您更新原始文档时,都会将旧的文本值复制到此表格中,复制用户和更改日期并提高版本。

select version, change_date, change_user, text_data 
    into l_version, l_change_data, l_change_user, l_text_data 
from docs where id = l_doc_id;

insert into versions values (newid, l_doc_id, l_version, 
    l_change_date, l_change_user, l_text_data);

update docs set version = version + 1, change_date = now, 
    change_user = cur_user, text_data = l_new_text where id = l_doc_id;

如果您的数据库支持触发器,甚至可以在触发器中执行此操作。

使用此方法的缺点是它对数据进行了完整复制(因此,如果您有一个大型文档,则版本会很大)。您可以通过使用类似于 diff(1) 和 patch(1) 的工具来减轻这种情况。

例如:

diff version2.txt version1.txt > difffile

然后您可以将该差异文件存储为“版本1”。

要从版本2恢复版本1,需要获取版本2数据,使用差分文件数据运行补丁程序,这会给您提供v1。

如果想从v3到v1,则需要执行此操作两次(一次获取v2,然后再次获取v1)。

这降低了您的存储负担,但增加了处理量(显然),因此您必须判断如何处理。


不错的方法,我会研究一下! - ack
与Mediawiki相比,这个程序非常简单高效。http://upload.wikimedia.org/wikipedia/commons/4/41/Mediawiki-database-schema.png - Cherian
顺便问一下,为什么您需要在文档表中更改日期(change_date)和更改用户ID(change_user_id),并将它们作为整数引用到用户表(users)中的ID?这些信息不能从版本表中推断出来吗? - Cherian
当然,唯一的问题是,如所示,文档表保存了文本的当前版本,而版本表保存了旧版本。因此,对于版本1,文档表将有1行,版本表将有0行,在这种情况下,您将无法捕获正确的用户。如果您在版本表中存储所有文档(包括当前版本),则可以从文档表中删除create_date、create_user、change_date和change_user。或者,您可以将文档表简单地链接到版本表中的最新版本。这里有各种各样的选择。 - Will Hartung
一个可能的增强功能:如果您预计会有大量修订和/或大型文件,那么通过补丁方式返回早期版本可能会变得处理繁重。如果这是您关心的问题,请考虑定期将完整版本存储在版本表中,例如每25个修订版本。添加一个布尔列来指示完整版本。然后,如果您想跳回200个版本,请查找您想要的版本之后的第一个完整版本,并从那里进行补丁; 将您的处理减少到最多24个补丁。您甚至可以在任一方向上找到最近的版本,这将是最多12个补丁,但我不知道这有多难。 - Ken Bellows

2
威尔的回答非常详细,但我认为可以简单概括一下:您需要存储版本,然后需要存储数据的元数据(谁、什么时候)。但是您的问题是关于类似Wiki的版本控制的资源。我没有太多(一个链接:上面的威尔的回答)。不过,关于Wiki的存储,我有一个资源。请查看DokuWiki的比较矩阵。我知道,你可能会想:“我为什么要关心不同Wiki使用的数据库品牌?”因为DokuWiki使用纯文本文件。您可以打开它们并确实是纯文本。因此,这是一种方法,他们提出了一些有趣的论点,说明DBMS并不是最好的选择,甚至不需要太多元数据:大部分内容都在平面文件中完成。对于您来说,DokuWiki的重点是,也许这是一个相对简单的问题(取决于您想解决得有多好 :)

0

这里是 WikiMatrix 上所有使用 PHP 编写并使用文本文件进行存储的 12 个维基列表。也许其中一个维基有一种存储方法,你可以将其适应到数据库中:

http://www.wikimatrix.org/search.php?sid=1760


0

听起来你只是在寻找版本控制。如果是这样,你可能需要研究一下差异算法。

这里是维基百科Diff页面。

我进行了快速的php diff谷歌搜索,但没有什么像一个体面的例子,因为我只有基本的PHP知识。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接