SQLite:我可以使用AUTOINCREMENT表反转行插入的顺序吗?

时间:2018-01-24 16:02:06

标签: database sqlite android-cursor

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

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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

首先,如果您担心间接费用,请使用推荐的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使用的数字高于此值,则会发生SQLITE_FULL异常。

再次关于rowid和搜索: -

  

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

  

为避免长时间搜索整套ROWID,有没有   将新插入的方法添加到数据库的顶部而不是   底部?

是的,只需在插入时指定rowid的值或通常指定别名(但要注意使用已使用的值并且好好管理编号)。但是,我怀疑这样做会导致更快的搜索。默认情况下,表具有rowid主要是因为rowid被优化以便通过rowid进行搜索。