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 是否提供任何其他 AUTOINCREMENTAUTOINCREMENT 类选项?

我在 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;

结果是:-

然后 :-