id INTEGER PRIMARY KEY 自己保证(要求)一个唯一的整数值,如果没有专门分配值,将提供一个,直到最高值达到 64 位有符号整数 (9223372036854775807) 的最高允许值,之后未使用可以找到并应用价值。
使用AUTOINCREMENT 可以保证(如果未规避)始终提供更高的值,但如果达到 9223372036854775807 而不是分配未使用的数字,则会导致 SQLITE_FULL 错误。从分配的数字来看,这是唯一的区别。
都不保证单调递增的值。
没有 AUTOINCREMENT 的计算/算法等价于
使用 AUTOINCREMENT 计算/算法是
大于 1 + max(rowid) 或 SELECT seq FROM sqlite_sequence WHERE name = 'the_table_name_the_rowid_is_being_assigned_to' 如果值大于 9223372036854775807 则 SQLITE_FULL ERROR。
请注意,无论哪种方式,最大 rowid 都有可能用于最终不会插入的行,因此可能存在间隙。
最好的答案可能是:最好/建议仅将 id 列用于其预期目的,即有效识别行而不是作为处理其他数据要求的手段,如果这样做,就不需要 AUTOINCREMENT (有overheads)
总之
是否保证id会自动递增
否
已删除行的值不会被重复使用?
NO对于给定的代码
对于:-
CREATE TABLE names (id INTEGER PRIMARY KEY AUTOINCREMENT name TEXT NOT NULL)
再次NO,如果达到 9223372036854775807 则会导致 SQLITE_FULL 错误,否则 YES。
所以真正的 AUTOINCREMENT 只有在插入第 9223372036854775807 行时才真正相关(如果 id 按预期/预期使用)。
也许考虑以下几点:-
DROP TABLE IF EXISTS table1;
DROP TABLE IF EXISTS table2;
CREATE TABLE IF NOT EXISTS table1 (id INTEGER PRIMARY KEY, somecolumn TEXT);
CREATE TABLE IF NOT EXISTS table2 (id INTEGER PRIMARY KEY AUTOINCREMENT, somecolumn TEXT);
INSERT INTO table1 VALUES (9223372036854775807,'blah');
INSERT INTO table2 VALUES (9223372036854775807,'blah');
INSERT INTO table1 (somecolumn) VALUES(1),(2),(3);
SELECT * FROM table1;
INSERT INTO table2 (somecolumn) VALUES(1),(2),(3);
这将创建两个相似的表,唯一的区别是使用 AUTOINCREMENT。每个都插入了 id 列允许的最高值的行。
然后尝试插入 3 行,其中 id 将由 SQLite 分配。
在没有 AUTOINCREMENT 的情况下将 3 行插入到表中,但在使用 AUTOINCREMENT 时不插入任何行。根据:-
CREATE TABLE IF NOT EXISTS table1 (id INTEGER PRIMARY KEY, somecolumn TEXT)
> OK
> Time: 0.098s
CREATE TABLE IF NOT EXISTS table2 (id INTEGER PRIMARY KEY AUTOINCREMENT, somecolumn TEXT)
> OK
> Time: 0.098s
INSERT INTO table1 VALUES (9223372036854775807,'blah')
> Affected rows: 1
> Time: 0.094s
INSERT INTO table2 VALUES (9223372036854775807,'blah')
> Affected rows: 1
> Time: 0.09s
INSERT INTO table1 (somecolumn) VALUES(1),(2),(3)
> Affected rows: 3
> Time: 0.087s
SELECT * FROM table1
> OK
> Time: 0s
INSERT INTO table2 (somecolumn) VALUES(1),(2),(3)
> database or disk is full
> Time: 0s
table1 的 SELECT 的结果(由于随机性可能会有所不同)是:-