SQLite AUTOINCREMENT 非主键列
SQLite AUTOINCREMENT non-primary key column
我有以下 SQLite table:
CREATE TABLE podcast_search (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
search TEXT NOT NULL UNIQUE
)
每当用户 inserts/updates table 中的一行时,我想在 table 末尾对该行进行排序。因此,如果我插入以下值:
_id | search | sort
===================
1 | foo | 1
2 | bar | 2
3 | quiz | 3
然后稍后将 1
行从 foo
更新为 foo2
,值应如下所示:
_id | search | sort
===================
2 | bar | 2
3 | quiz | 3
1 | foo2 | 4
我是这样实现的:
CREATE TABLE podcast_search (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
search TEXT NOT NULL UNIQUE,
update_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)
CREATE TRIGGER update_date_update_trigger
AFTER UPDATE ON podcast_search FOR EACH ROW
BEGIN
UPDATE podcast_search
SET update_date = CURRENT_TIMESTAMP
WHERE _id = OLD._id;
END
但是,我的单元测试需要 1000ms
在 insert/update 操作之间休眠以便可靠地排序,这种延迟对于单元测试来说非常烦人。
我以为我可以实现一个矢量时钟,但似乎 AUTOINCREMENT
值只存在于主键列中。 SQLite 是否提供任何其他 AUTOINCREMENT
或 AUTOINCREMENT
类选项?
我在 Android P 上 运行,但这应该是一个通用的 SQLite 问题。
更新
我现在正在使用 sort INTEGER NOT NULL UNIQUE
列,并且 SELECT
-ing 该列中最大的行并在 INSERT/UPDATE
:
之前手动递增它
CREATE TABLE podcast_search (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
search TEXT NOT NULL UNIQUE,
sort INTEGER NOT NULL UNIQUE
)
SELECT sort from podcast_search ORDER BY sort DESC
在应用程序代码中递增 sort
,或将其设置为 0
我可以在 TRIGGER
中执行此操作吗?
I thought I could implement a vector clock instead, but it seems that
AUTOINCREMENT values only exist for primary key columns. Does SQLite
offer any other AUTOINCREMENT or AUTOINCREMENT-like option?
它们实际上不是 AUTOINCREMENT 值,而是具有 AUTOINCREMENT 的列将是 rowid 列的别名;不是因为 AUTOINCREMENT 已被编码,而是因为 INTEGER PRIMARY KEY 已被编码。
AUTOINCREMENT 所做的所有编码都是添加一个约束,即自动生成的值必须大于任何其他现有或使用的值。如果存在值为 9223372036854775807 的 rowid,这实际上只会变得明显。在这种情况下,尝试插入具有自动生成的 rowid 的新行(即没有为 rowid 列或其别名指定值)将导致 SQLITE_FULL 错误。
没有 AUTOINCREMENT 并且当最高 rowid 为 9223372036854775807(rowid 的最高可能值)时,尝试使用一个自由值,该值显然低于 9223372036854775807。
SQLite Autoincrement
您可能希望注意链接页面的第一行:-
The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and
disk I/O overhead and should be avoided if not strictly needed. It is
usually not needed.
从你的描述中看不出有什么需要
所以你想要的是一种为要排序的列分配一个值的方法,该值比该列的当前最高值大 1,因此它成为排序目的的最新子查询,检索max(the_column) + 1
随心所欲。这可能在 UPDATE、TRIGGER 或 INSERT 中。
rowid = max(rowid) + 1
基本上是 SQLite 将值分配给 rowid 的方式,除非在将 1 添加到 max(rowid) 和值中的较大者时使用 AUTOINCREMENT,对于相应的 table,从table sqlite_sequence(仅当使用 AUTOINCREMENT 时才会存在)。引用和维护 sqlite_sequence 会受到惩罚。
例如,您可以使用以下内容(这消除了对附加列和附加索引的需要):-
-- SETUP THE DATA FOR TESTING
DROP TABLE IF EXISTS podcast_searchv1;
CREATE TABLE IF NOT EXISTS podcast_searchv1 (
_id INTEGER NOT NULL PRIMARY KEY,
search TEXT NOT NULL UNIQUE
);
INSERT INTO podcast_searchv1 (search)
VALUES('foo'),('bar'),('guide')
;
-- Show original data
SELECT * FROM podcast_searchv1;
-- DO THE UPDATE
UPDATE podcast_searchv1 SET search = 'new value', _id = (SELECT max(_id) + 1 FROM podcast_searchv1) WHERE search = 'foo';
-- Show the changed data
SELECT * FROM podcast_searchv1;
结果是:-
然后 :-
我有以下 SQLite table:
CREATE TABLE podcast_search (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
search TEXT NOT NULL UNIQUE
)
每当用户 inserts/updates table 中的一行时,我想在 table 末尾对该行进行排序。因此,如果我插入以下值:
_id | search | sort
===================
1 | foo | 1
2 | bar | 2
3 | quiz | 3
然后稍后将 1
行从 foo
更新为 foo2
,值应如下所示:
_id | search | sort
===================
2 | bar | 2
3 | quiz | 3
1 | foo2 | 4
我是这样实现的:
CREATE TABLE podcast_search (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
search TEXT NOT NULL UNIQUE,
update_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)
CREATE TRIGGER update_date_update_trigger
AFTER UPDATE ON podcast_search FOR EACH ROW
BEGIN
UPDATE podcast_search
SET update_date = CURRENT_TIMESTAMP
WHERE _id = OLD._id;
END
但是,我的单元测试需要 1000ms
在 insert/update 操作之间休眠以便可靠地排序,这种延迟对于单元测试来说非常烦人。
我以为我可以实现一个矢量时钟,但似乎 AUTOINCREMENT
值只存在于主键列中。 SQLite 是否提供任何其他 AUTOINCREMENT
或 AUTOINCREMENT
类选项?
我在 Android P 上 运行,但这应该是一个通用的 SQLite 问题。
更新
我现在正在使用 sort INTEGER NOT NULL UNIQUE
列,并且 SELECT
-ing 该列中最大的行并在 INSERT/UPDATE
:
CREATE TABLE podcast_search (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
search TEXT NOT NULL UNIQUE,
sort INTEGER NOT NULL UNIQUE
)
SELECT sort from podcast_search ORDER BY sort DESC
在应用程序代码中递增 sort
,或将其设置为 0
我可以在 TRIGGER
中执行此操作吗?
I thought I could implement a vector clock instead, but it seems that AUTOINCREMENT values only exist for primary key columns. Does SQLite offer any other AUTOINCREMENT or AUTOINCREMENT-like option?
它们实际上不是 AUTOINCREMENT 值,而是具有 AUTOINCREMENT 的列将是 rowid 列的别名;不是因为 AUTOINCREMENT 已被编码,而是因为 INTEGER PRIMARY KEY 已被编码。
AUTOINCREMENT 所做的所有编码都是添加一个约束,即自动生成的值必须大于任何其他现有或使用的值。如果存在值为 9223372036854775807 的 rowid,这实际上只会变得明显。在这种情况下,尝试插入具有自动生成的 rowid 的新行(即没有为 rowid 列或其别名指定值)将导致 SQLITE_FULL 错误。
没有 AUTOINCREMENT 并且当最高 rowid 为 9223372036854775807(rowid 的最高可能值)时,尝试使用一个自由值,该值显然低于 9223372036854775807。 SQLite Autoincrement
您可能希望注意链接页面的第一行:-
The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and disk I/O overhead and should be avoided if not strictly needed. It is usually not needed.
从你的描述中看不出有什么需要
所以你想要的是一种为要排序的列分配一个值的方法,该值比该列的当前最高值大 1,因此它成为排序目的的最新子查询,检索max(the_column) + 1
随心所欲。这可能在 UPDATE、TRIGGER 或 INSERT 中。
rowid = max(rowid) + 1
基本上是 SQLite 将值分配给 rowid 的方式,除非在将 1 添加到 max(rowid) 和值中的较大者时使用 AUTOINCREMENT,对于相应的 table,从table sqlite_sequence(仅当使用 AUTOINCREMENT 时才会存在)。引用和维护 sqlite_sequence 会受到惩罚。
例如,您可以使用以下内容(这消除了对附加列和附加索引的需要):-
-- SETUP THE DATA FOR TESTING
DROP TABLE IF EXISTS podcast_searchv1;
CREATE TABLE IF NOT EXISTS podcast_searchv1 (
_id INTEGER NOT NULL PRIMARY KEY,
search TEXT NOT NULL UNIQUE
);
INSERT INTO podcast_searchv1 (search)
VALUES('foo'),('bar'),('guide')
;
-- Show original data
SELECT * FROM podcast_searchv1;
-- DO THE UPDATE
UPDATE podcast_searchv1 SET search = 'new value', _id = (SELECT max(_id) + 1 FROM podcast_searchv1) WHERE search = 'foo';
-- Show the changed data
SELECT * FROM podcast_searchv1;
结果是:-
然后 :-