2

〜2 ^ 40ページの本があるとしましょう。毎日、連続したページのランダムなチャンクを読みます (時には既に読んだページを含むこともあります)。(SQLite) データベースで「どのページを読んだか」の情報を保存および更新する最もスマートな方法は何ですか?

私の現在の考えは、[firstChunkPage, lastChunkPage] エントリをテーブルに保存することですが、これを効率的に更新する方法がわかりません。

  • 最初にすべての可能なオーバーラップをチェックしてから更新する必要がありますか?
  • 新しい範囲を挿入してから、重複するエントリをマージする必要があります (複数の重複が発生する可能性があるため、おそらく複数回ですか?) このような SQL クエリを作成する方法がわかりません。

これはかなり一般的な問題のように見えるので、これに対する「認識された」解決策を誰かが知っているかどうか疑問に思っています。

どんな助けやアイデアも大歓迎です!

編集: 読み取りは実際にはランダムではありません。チャンクの数はページ数に比べてほぼ一定で非常に小さいと予想されます。

4

1 に答える 1

3

(firstChunkPage, lastChunkPage)データが比較的まばらな場合は、ペアの範囲を保存するというアイデアが機能するはずです。

残念ながら、あなたが言及したようなクエリ:

SELECT count(*) FROM table
WHERE firstChunkPage <= page AND page <= lastChunkPage

空間インデックスを使用しないと、効果的に機能しません。

SQLite の場合、この種のインデックスのサポートを実装するR-Tree モジュールを使用する必要があります。見積もり:

R ツリーは、範囲クエリを実行するために設計された特別なインデックスです。R ツリーは、各エントリが X 座標と Y 座標の最小値と最大値を持つ四角形である地理空間システムで最も一般的に使用されます。... たとえば、データベースに多数のイベントの開始時刻と終了時刻が記録されているとします。R ツリーは、たとえば、特定の時間間隔中にアクティブだったすべてのイベント、特定の時間間隔中に開始されたすべてのイベント、または特定の時間内に開始および終了したすべてのイベントをすばやく見つけることができます。間隔。

R-Tree を使用すると、新しい範囲を挿入する前にすべてのオーバーラップを非常に迅速に特定し、それらを新しい結合エントリに置き換えることができます。

RTree インデックスを作成するには、次のようなものを使用します。

CREATE VIRTUAL TABLE demo_index USING rtree(
    id, firstChunkPage, lastChunkPage
);

詳細については、ドキュメントを参照してください。

于 2013-06-01T19:10:09.137 に答える