3

我先搜索了几次,还有一个问题。

远远地,我找到的最好的答案就是在这个SO 答案中。总结:

SELECT * FROM TABLE WHERE ID = (SELECT MAX(ID) FROM TABLE);

我想知道的是下面的方法是否同样有效(因为我懒得改变它,我碰巧喜欢它)。

SELECT * FROM TABLE ORDER BY ID DESC LIMIT 1

根据我们拥有的SQLite Autoincrement文档,

如果插入时没有指定 ROWID,或者指定的 ROWID 的值为 NULL,则会自动创建适当的 ROWID。通常的算法是给新创建的行一个比插入前表中最大的 ROWID 大一的 ROWID。如果表最初为空,则使用 1 的 ROWID。[重点补充]

并进一步,

只要您从不使用最大 ROWID 值并且您从不删除表中具有最大 ROWID 的条目,上述常规 ROWID 选择算法将生成单调递增的唯一 ROWID。如果您曾经删除行或曾经创建具有最大可能 ROWID 的行,则在创建新行时可能会重用先前删除的行中的 ROWID,并且新创建的 ROWID 可能不会严格按升序排列。 [重点补充]

我对我提出的 SQL 语句的问题来自最后一句话。这似乎表明,如果您删除任何行,则可以重用先前删除的 ROWID,而不管是否使用了最大 ROWID。如果我们假设从未使用过最大 ROWID(手动或仅通过那么多记录),那么我们只需要担心删除记录。在这种情况下,第一个 SQLite 文档摘录听起来好像您不会在我的查询中遇到任何问题。

有人有确切消息么?

我喜欢我的查询,因为它只涉及一个选择(虽然,以订购为代价)。我想,我可能过于关注微小的优化,不是吗?

编辑:实际上,重新查看上面引用的 SQLite 页面,我认为使用 AUTOINCREMENT 关键字可以保证 ROWID 单调递增。最后一节详细讨论了它。

如果列的类型为 INTEGER PRIMARY KEY AUTOINCREMENT,则使用稍微不同的 ROWID 选择算法。为新行选择的 ROWID 至少比以前存在于同一个表中的最大 ROWID 大一个。如果表以前从未包含任何数据,则使用 1 的 ROWID。如果该表之前保存了具有最大可能 ROWID 的行,则不允许新的 INSERT,并且任何插入新行的尝试都将失败并返回 SQLITE_FULL 错误。

现在对我来说似乎很清楚。只是无法填满表格(最多 9223372036854775807)。

对不起,我之前只略过这部分!

4

4 回答 4

4

我想我会在这里写一点关于这两个查询运行的速度。
在一张有大约 15,000 行的表上,抓取其中的 1400 行,然后获取最后输入的行,这就是我得到的结果:

SELECT macAddr, time, onPeakTotalIn, onPeakTotalOut, offPeakTotalIn, offPeakTotalOut FROM trafficMon WHERE macAddr="02:d2:ee:aa:aa:aa" ORDER BY time DESC LIMIT 1;

CPU 时间:用户 0.008124 sys 0.000000
虚拟机步数:58741 全扫描
步数:14156

SELECT macAddr, time, onPeakTotalIn, onPeakTotalOut, offPeakTotalIn, offPeakTotalOut FROM trafficMon WHERE id = (SELECT MAX(id) FROM trafficMon WHERE macAddr="02:d2:ee:aa:aa:aa");

CPU 时间:用户 0.000295 sys 0.000000
虚拟机步骤:49全
扫描步骤:3

如您所见,明智地执行 MAX(id) 资源要容易得多,而且花费的时间要少得多。

虽然 0.008124s 一直都是错误的,但当您在基于 MIPS 的嵌入式设备(在我的例子中是路由器)上运行相同的命令时,在脚本中运行 20-30 倍以及一堆其他东西,所有这些都会加起来。

希望有帮助:)

鸭子

于 2015-01-11T03:39:59.473 回答
3

您显示的两个查询是等效的。

至于他们是否返回最后一条记录,这取决于您所说的“最后一条”是什么意思。如果删除行,则不能依赖任一查询来返回最后插入的行。

于 2012-08-01T19:44:44.577 回答
1

首先,您应该检索最后插入的行 id,然后从该行 id 中,您可以通过选择查询获取最后插入的记录。

RowID = sqlite3_last_insert_rowid(sqlite3Database)

SELECT * FROM tableName where RowID=RowID

此选择语句将为您提供最后插入的记录

在此链接中获取更多详细信息。

于 2015-01-11T05:39:13.140 回答
1

如果 table 有一个类型为“autoincrement”的字段,那么最好使用:

SELECT seq FROM sqlite_sequence WHERE name='TABLE_NAME'

查看示例(对于表“客户”):

SELECT seq FROM sqlite_sequence WHERE name='customers'
于 2015-11-17T03:31:09.637 回答