私は最近、ウィキペディアの「リンク先」機能 (エントリの左メニューの「ツールボックス」要素の下にあります) を使用しましたが、この機能が実際にどのように機能するのか疑問に思い始めました。
リンクの後にすべての記事エントリを検索するのはあまり効果的ではないと推測していますが、すべてのリンクは別のデータベースに保存されているのでしょうか? もしそうなら、これは記事が編集されたとき、または別のときに更新されますか?
ありがとう。
ウィキペディアのページが編集されるたびに、バックグラウンド キューに配置され、さらに処理が行われます。そこで起こることのいくつかは次のとおりです。
この種の情報は、[送信] を押したときにすぐに更新する必要はないため、バックグラウンド処理キューが処理します。場合によっては、このキューが非常に大きくなることがありますが、通常は制御されています。
これについての詳細はHelp:Job Queueで見つけることができます。
これは、より一般的な問題と考えることができます。AからBへのリンク(またはポインタなど)がある場合、BはAがそこを指すリンクを持っていることをどのようにして知ることができますか?
答えは、情報をターゲットの場所に保存することです。つまり、ページAが編集され、Bへのリンクが作成されると同時に、Bへのリンクソース(逆リンク)に関する情報が保存されます。ウェブページの場合、逆リンクは「ここにリンクするもの」ページに直接書き込むことができます。静的ページへの書き込みは1回だけです。検索やデータベースクエリを実行する必要はありません。
それを行う単純なアルゴリズムの擬似コード
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 を使用してテーブルをクエリし、そのページへのリンクとしてマークされているすべてのリンクを取得できます。
おそらくそれほど単純ではないでしょうが、それは一般的で単純化された考え方です。おそらく、URL の代わりにページ ID などを保存する方が賢明でしょう。
記事が変更されるのはこれだけなので、記事の「更新イベント」がリンク パーサーをトリガーするのは理にかなっています。更新イベントは、単純にリンクをスキャンし、ウィキペディア内部のリンクをデータベースに照会します。
各ページには主キーがあり、単純な関連付けテーブルが作成されて、ページ PK がそれにリンクされている他のすべてのページに関連付けられていると思います。
このような大規模なサイトでのパフォーマンスを向上させるために追加されるビットがいくつかある可能性がありますが、それが基本的な仕組みです。