删除行后的sqlite rowid

标签 sqlite

我创建了带有列 id、name 的 sqlite 表 tmp。

CREATE TABLE if not exists tmp (
            id             INTEGER PRIMARY KEY,
            name            TEXT NOT NULL);

我在其中插入了 5 行。

当我使用 rowid 列运行选择查询时,它会给出以下输出。
select rowid,id,name from tmp;

rowid  id    name
1      1     a
2      2     b
3      3     c
4      4     d
5      5     e

现在我删除 id 为 3 和 4 的行并再次运行上面的查询。
rowid  id    name
1      1     a
2      2     b
5      5     e

现在我的问题是 rowid 没有重置和漏洞。

即使在执行vacuum之后,它仍然不会重置rowid,它仍然给出以上输出。

我想要的输出是
rowid id  name
1      1  a
2      2  b
3      5  e

有人可以帮助我实现上述输出吗?

谢谢

最佳答案

我假设您已经对 rowid 有所了解,因为您问的是它与 VACUUM 的交互命令,但这对 future 的读者可能是有用的信息:
rowida special column available in all tables (除非您使用 WITHOUT ROWID ),由 sqlite 内部使用。一个 VACUUM应该重建表,旨在减少数据库文件中的碎片,和may change the values of the rowid column .继续。

这是您问题的答案:rowid真的很特别。非常特别,如果您有 INTEGER PRIMARY KEY ,它成为 rowid 的别名柱子。来自 rowid 上的文档:

With one exception noted below, if a rowid table has a primary key that consists of a single column and the declared type of that column is "INTEGER" in any mixture of upper and lower case, then the column becomes an alias for the rowid. Such a column is usually referred to as an "integer primary key". A PRIMARY KEY column only becomes an integer primary key if the declared type name is exactly "INTEGER". Other integer type names like "INT" or "BIGINT" or "SHORT INTEGER" or "UNSIGNED INTEGER" causes the primary key column to behave as an ordinary table column with integer affinity and a unique index, not as an alias for the rowid.



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

The data for rowid tables is stored as a B-Tree structure containing one entry for each table row, using the rowid value as the key. This means that retrieving or sorting records by rowid is fast. Searching for a record with a specific rowid, or for all records with rowids within a specified range is around twice as fast as a similar search made by specifying any other PRIMARY KEY or indexed value.



当然,当您的主键是 rowid 的别名时,如果这能改变,那将是非常不方便的。自 rowid现在别名为您的应用程序数据,sqlite 更改它是 Not Acceptable 。

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

The VACUUM command may change the ROWIDs of entries in any tables that do not have an explicit INTEGER PRIMARY KEY.



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

为避免混叠并降低性能,您可以使用 INT而不是 INTEGER定义 key 时:

A PRIMARY KEY column only becomes an integer primary key if the declared type name is exactly "INTEGER". Other integer type names like "INT" or "BIGINT" or "SHORT INTEGER" or "UNSIGNED INTEGER" causes the primary key column to behave as an ordinary table column with integer affinity and a unique index, not as an alias for the rowid.

关于删除行后的sqlite rowid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35876171/

相关文章:

android - 日期为 SectionHeader 的自定义 ListView(使用自定义 SimpleCursorAdapter)

java - 通过 Jsoup 更新效果不佳

mysql - SQL查询多对多JOIN中存在的多个关系

java - 我看不到数据,也看不到我创建的 sqlite 表

java - 数据库不会更新编辑文本更改android

java - Android - 使用另一个 Activity 的变量

sqlalchemy 使用 json_set 更新特定的 JSON 字段

node.js - 如何在 Electron 中安装sqlite3?

c# - SQLite BackupDatabase 方法在升级到版本 1.0.111.0 后抛出异常

c# - Windows 应用商店应用程序中的 SQLite 异常