SQLite AUTOINCREMENT非主键列

时间:2019-02-17 07:35:45

标签: sqlite auto-increment

我有以下SQLite表:

CREATE TABLE podcast_search (
        _id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
        search TEXT NOT NULL UNIQUE
)

每当用户在表格中插入/更新一行时,我都希望在表格末尾对该行进行排序。因此,如果我插入以下值:

_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睡眠才能可靠地进行排序,而这种延迟量对于单元测试来说是非常烦人的。

我认为我可以改为实现矢量时钟,但是似乎AUTOINCREMENT值仅存在于主键列中。 SQLite是否提供其他类似AUTOINCREMENTAUTOINCREMENT的选项?

我正在Android P上运行它,但这应该是通用的SQLite问题。

更新

我现在使用的是sort INTEGER NOT NULL UNIQUE列,并SELECT-插入该列中的最大行,并在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吗?

1 个答案:

答案 0 :(得分:1)

  

我以为我可以实现向量时钟,但是似乎   AUTOINCREMENT值仅适用于主键列。是否SQLite   是否提供其他任何AUTOINCREMENT或类似AUTOINCREMENT的选项?

它们实际上不是AUTOINCREMENT值,而是具有AUTOINCREMENT的列将是 rowid 列的别名;不是因为已经编码了AUTOINCREMENT,而是因为已经编码了INTEGER PRIMARY KEY。

AUTOINCREMENT的所有编码都添加了一个约束,即自动生成的值必须大于任何其他现有或使用的值。实际上,只有当存在具有值9223372036854754775807的 rowid 时,这才变得明显。在这种情况下,尝试插入具有自动生成的rowid的新行(即,未为rowid列或其别名指定任何值)将导致SQLITE_FULL错误。

没有AUTOINCREMENT且最高的rowid为9223372036854754775807(rowid的最大可能值)时,尝试使用自由值,该值显然低于922337203685477575807。 SQLite Autoincrement

  • 您可能希望注意链接页面的第一行::-

  •   

    AUTOINCREMENT关键字强加了额外的CPU,内存,磁盘空间和   磁盘I / O开销,如果没有严格要求,则应避免。它是   通常不需要。

  • 我从您的描述中看不到任何需要。

因此,您想要的是一种为要排序的列分配一个比该列的当前最高值大1的值的方法,因此它成为最新的排序目的,子查询可检索{{ 1}}会做您想要的。这可以在UPDATE,TRIGGER或INSERT中。

  • max(the_column) + 1基本上是SQLite如何为rowid分配一个值,除非将max(rowid)和从表 sqlite_sequence获得的相应表的值中的较大者加1时使用AUTOINCREMENT。 (仅在使用AUTOINCREMENT的情况下存在)。引用并维护 sqlite_sequence 会导致罚款。

例如,您可以使用以下命令(这样就不需要附加的列和索引):-

rowid = max(rowid) + 1

结果是:-

enter image description here

然后::-

enter image description here