我创建了带有列 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 的读者可能是有用的信息:rowid
是 a 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.
如果您真的真的真的绝对需要
rowid
在 VACUUM
上更改(我不明白为什么——请在评论中随意讨论您的原因,我可能有一些建议),您可以避免这种混叠行为。请注意,它会降低使用主键的任何表查找的性能。为避免混叠并降低性能,您可以使用
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/