我最近使用了维基百科的功能“这里有什么链接”(位于任何条目左侧菜单的“工具箱”元素下),它让我开始想知道这个功能是如何工作的。
我猜在链接之后搜索所有文章条目不是很有效,那么所有链接都存储在单独的数据库中吗?如果是这样,这是在编辑文章时更新还是在其他时间更新?
谢谢。
每当编辑 Wikipedia 上的页面时,都会将其放入后台队列中进行进一步处理。那里发生的一些事情是:
当您点击“提交”时,此类信息不需要立即更新,因此后台处理队列会处理它。有时这个队列会变得非常大,但通常它会受到控制。
您可以在Help:Job Queue中找到更多信息。
你可以认为这是一个更普遍的问题。如果您有从 A 到 B 的链接(或指针或其他),B 怎么知道 A 有指向那里的链接?
答案是将信息存储到目标位置。即,当编辑页面A并创建到B的链接时,同时存储关于到B的链接源的信息(反向链接)。在网页的情况下,反向链接可以直接写入“这里有什么链接”页面。只需一次写入静态页面。无需执行任何搜索或数据库查询。
一个简单算法的伪代码,可以做到这一点
procedure updateChanges(editedPage):
for_each(link on editedPage):
if(link is not to another wikipedia page): continue
pageToUpdate = open(link):
if(pageToUpdate->whatLinksHere.contains(editedPage)): continue
pageToUpdate->whatLinksHere.insert(editedPage)
对不起,我刚刚完成了我的算法课,所以我有一种写伪代码的冲动。在这种情况下,该updateChanges()
过程将在 Greg Hewgill 提到的“更新其他页面的‘这里的链接’”阶段调用。
我将实现的方式是在编辑后获取所有链接,然后将它们存储在单独的表中,键为当前 url。然后我可以使用用户当前所在的 URL 查询表,并获取所有标记为链接到该页面的链接。
它可能不会那么简单,但这是一般的、简化的想法。存储页面 ID 等可能比 URL 更明智。
文章的“更新事件”触发链接解析器是有意义的,因为这是文章唯一会更改的时间。反过来,更新事件将简单地扫描链接,并在数据库中查询维基百科内部的链接。
我想每个页面都有一个主键,并创建一个简单的关联表来将页面 PK 与链接到它的所有其他页面相关联。
可能会添加一些额外的位来帮助在如此大的站点上提高性能,但这将是基本机制。