【问题标题】:SQLite: can I reverse the order of row inserts with an AUTOINCREMENT Table?SQLite:我可以用 AUTOINCREMENT 表反转行插入的顺序吗?
【发布时间】:2018-07-03 17:56:54
【问题描述】:

我有一个使用 SQLite 数据库存储用户输入数据的 RecyclerView 项目列表。我使用传统的 _id 列作为 INTEGER PRIMARY KEY AUTOINCREMENT。如果我理解正确,数据库中新插入的行将添加到现有行下方,新的 ROWID 采用最大的现有 ROWID 并将其增加 +1。因此,对最新插入的游标搜索将不得不向下扫描整个行集以到达数据库的底部。例如,插入 10 次后,光标必须从 1、2、3、... 向下搜索,直到到达第 10 行。

为了避免对整个 ROWID 集进行冗长的搜索,有没有办法将新的插入添加到数据库的顶部而不是底部?这样,使用 moveToFirst() 对最新插入的游标搜索将非常快,因为游标将停在它搜索的第一行,即数据库的顶部。游标将搜索 10、9、8、...3、2、1,因此搜索会非常快,因为它会在 10 处停止,即数据库顶部的第一行。

【问题讨论】:

  • 您是否假设所有数据库查询都使用按 ROWID 升序排列的线性搜索?

标签: database sqlite android-cursor


【解决方案1】:

您对数据库内部的考虑太多了。索引就是为这种优化而设计的。

创建一个新的数字列,将您希望的排序作为一个值并在选择中使用order by。不要忘记在此列上创建索引并验证您的选择是否使用索引。 (explain)

【讨论】:

  • 好的,我明白了。但是,我是 SQLite 和 Android 的新手,所以必须研究您的建议,因为我不知道如何实施。
【解决方案2】:

首先,如果您担心开销,请使用推荐的INTEGER PRIMARY KEY,而不是INTEGER PRIMARY KEY AUTOINCREMENT。两者都会产生一个唯一的 id,后者有开销:-

AUTOINCREMENT 关键字强加了额外的 CPU、内存、磁盘空间和 磁盘 I/O 开销,如果不是严格需要,应该避免。它是 通常不需要。 SQLite Autoincrement


如果我理解正确,数据库中新插入的行是 添加在现有行下方,新的 ROWID 采用现有的最大 ROWID 并将其递增 +1。

通常但不一定,不能保证该值会增加 1。

AUTOINCREMENT 使用一个名为 sqlite_seqeunce 的表,每个表有一行存储上次使用的最高序列号以及表名。下一个序列号将是该值 + 可能是 1,除非最高 rowid 大于 sqlite_sequence 表中的值。

如果没有 AUTOINCREMENT,那么下一个序列是最高的 rowid + 可能是 1。

AUTOINCREMENT 保证更高的数字。如果没有 AUOINCREMENT,可以使用较小的数字(但直到数字大于 9223372036854775807)。如果 AUTOINCREMENT 使用比 this 更高的数字,则会发生 SQLITE_FULL 异常。

再次关于 rowid 和搜索:-

rowid 表的数据存储为 B-Tree 结构,其中包含 每个表行都有一个条目,使用 rowid 值作为键。这 表示按 rowid 检索或排序记录很快。搜索 对于具有特定 rowid 的记录,或对于具有 rowids 的所有记录 在指定范围内的速度大约是类似搜索的两倍 通过指定任何其他 PRIMARY KEY 或索引值来生成。 ROWIDs and the INTEGER PRIMARY KEY


为了避免对整个 ROWID 集进行冗长的搜索,是否有任何 将新插入添加到数据库顶部而不是 底部?

是的,只需在插入时指定 rowid 的值或通常的别名(但请注意使用已使用的值并祝您好运管理编号)。但是,我怀疑这样做会导致更快的搜索。默认情况下,表格有一个 rowid,这主要是因为 rowid 针对按 rowid 搜索进行了优化。

【讨论】:

    猜你喜欢
    • 2018-11-30
    • 2020-04-06
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多