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-Tree 是一种特殊的索引,专为进行范围查询而设计。R-Trees 最常用于地理空间系统,其中每个条目都是一个具有最小和最大 X 和 Y 坐标的矩形。...例如,假设数据库记录了大量事件的开始和结束时间。R-Tree 能够快速找到所有事件,例如,在给定时间间隔内的任何时间处于活动状态的事件,或在特定时间间隔内开始的所有事件,或在给定时间内开始和结束的所有事件间隔。

使用 R-Tree,您可以在插入新范围之前非常快速地识别所有重叠并用新的组合条目替换它们。

要创建 RTree 索引,请使用以下内容:

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

有关更多信息,请阅读文档

于 2013-06-01T19:10:09.137 回答