请考虑以下表格定义:
CREATE TABLE names (
id INTEGER,
name TEXT NOT NULL,
PRIMARY KEY (id)
)
是否保证每个新插入的id
都会自动递增,并且删除行的值不会重复使用?
我在Sqlite3的文档中进行了查找,但找不到答案。
答案 0 :(得分:0)
id INTEGER PRIMARY KEY
自己保证(要求)一个唯一的整数值,如果没有专门指定值,则将提供一个,直到最大值达到64位带符号整数的最大允许值(9223372036854775807)之后可能会发现并应用未使用的值。
如果使用AUTOINCREMENT
,则可以保证(如果未规避的话)始终提供更高的BUT值(如果达到了9223372036854775807),而不是分配未使用的数字,将导致SQLITE_FULL错误。从分配数字的角度来看,这是唯一的区别。
都不能保证单调递增的值。
没有AUTOINCREMENT的计算/算法等效于
1 + max(rowid),如果该值大于9223372036854754775807,则会尝试查找未使用的值,因此会找到较低的值。
对于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会自动递增
否
给定代码的已删除行的值将不会重复使用?
否
用于:-
CREATE TABLE names (id INTEGER PRIMARY KEY AUTOINCREMENT name TEXT NOT NULL)
再次否,就像到达9223372036854754775807一样,将导致SQLITE_FULL错误,否则为是。
因此,仅当插入第9223372036854754775807的行时,AUTOINCREMENT才真正有意义(如果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行,其中SQLite将分配 id 。
在没有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
表1的SELECT结果(可能由于随机性而有所不同)为:-