删除行后的sqlite rowid

use*_*687 5 sqlite

我创建了带有列ID,名称的sqlite表tmp。

CREATE TABLE if not exists tmp (
            id             INTEGER PRIMARY KEY,
            name            TEXT NOT NULL);
Run Code Online (Sandbox Code Playgroud)

我在其中插入了5行。

当我运行带有rowid列的select查询时,它给出以下输出。

select rowid,id,name from tmp;

rowid  id    name
1      1     a
2      2     b
3      3     c
4      4     d
5      5     e
Run Code Online (Sandbox Code Playgroud)

现在,我删除ID为3和4的行,然后再次运行以上查询。

rowid  id    name
1      1     a
2      2     b
5      5     e
Run Code Online (Sandbox Code Playgroud)

现在我的问题是rowid不能重置和漏洞。

即使在执行真空操作后,它仍然不会重置rowid,它仍然提供上述输出。

我想要的输出是

rowid id  name
1      1  a
2      2  b
3      5  e
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我实现上述目标吗?

谢谢

Sni*_*kow 8

我假设您已经对 有所了解rowid,因为您正在询问它与VACUUM命令的交互,但这对未来的读者可能是有用的信息:

rowid所有表中都可用的特殊列(除非您使用WITHOUT ROWID),由 sqlite 内部使用。AVACUUM应该重建表,旨在减少数据库文件中的碎片,并且可能会更改rowid列的值。继续。

这里的回答你的问题:rowid真的很 特别。非常特别,如果您有一个INTEGER PRIMARY KEY,它将成为该rowid列的别名。从关于rowid的文档:

除了下面提到的一个例外,如果 rowid 表有一个由单个列组成的主键,并且该列的声明类型是大小写混合的“INTEGER”,那么该列将成为 rowid 的别名。这样的列通常称为“整数主键”。如果声明的类型名称恰好是“INTEGER”,则 PRIMARY KEY 列仅成为整数主键。其他整数类型名称(如“INT”或“BIGINT”或“SHORT INTEGER”或“UNSIGNED INTEGER”)导致主键列表现为具有整数关联和唯一索引的普通表列,而不是作为 rowid 的别名。

这使您的主键比其他方式更快(大概是因为没有从主键到 的查找rowid):

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

当然,当您的主键是 的别名时rowid,如果这可以更改将非常不方便。由于rowid现在别名为您的应用程序数据,因此 sqlite 更改它是不可接受的。

因此,VACUUM 文档中的这个小说明:

VACUUM 命令可以更改没有显式 INTEGER PRIMARY KEY 的任何表中条目的 ROWID

如果您真的真的真的绝对需要rowid更改 a VACUUM(我不明白为什么 - 请随时在评论中讨论您的原因,我可能有一些建议),您可以避免这种混叠行为。请注意,它会降低使用主键的任何表查找的性能。

为避免混叠并降低性能,您可以在定义密钥时使用INT代替INTEGER

如果声明的类型名称恰好是“INTEGER”,则 PRIMARY KEY 列仅成为整数主键。其他整数类型名称(如“INT”或“BIGINT”或“SHORT INTEGER”或“UNSIGNED INTEGER”)导致主键列表现为具有整数关联和唯一索引的普通表列,而不是作为 rowid 的别名。