当前位置: 首页 > 科技观察

SQLiteAUTOINCREMENT你需要知道的知识

时间:2023-03-14 08:18:10 科技观察

1。总结AUTOINCREMENT关键字会占用额外的CPU、内存、磁盘空间和磁盘I/O开销,如果不是严格需要的话应该避免使用。通常情况下,不需要。在SQLite中,INTEGERPRIMARYKEY类型的列是ROWID的别名(WITHOUTROWID表除外),它们始终是64位有符号整数。在INSERT上,如果没有为ROWID或INTEGERPRIMARYKEY列明确给出值,它将自动填充一个未使用的整数,通常比当前使用的最大ROWID多一个。无论是否使用AUTOINCREMENT关键字都是如此。如果AUTOINCREMENT关键字出现在INTEGERPRIMARYKEY之后,则会更改自动ROWID分配算法以防止ROWID在数据库的生命周期内重用。换句话说,AUTOINCREMENT的目的是防止重复使用以前删除的行的ROWID。2.背景在SQLite中,表行通常有一个64位有符号整数ROWID,它在同一个表的所有行中是唯一的。(没有ROWID表是例外。)您可以使用特殊列名ROWID、_ROWID_或OID之一来访问SQLite表的ROWID。除非您声明普通表列使用其中一个特殊名称,否则使用该名称将引用声明的列而不是内部ROWID。如果表包含INTEGERPRIMARYKEY类型的列,则该列成为ROWID的别名。然后您可以使用四个不同名称中的任何一个访问ROWID,上面描述的原始三个名称或给INTEGERPRIMARYKEY列的名称。所有这些名称都是彼此的别名,在任何情况下都同样有效。当向SQLite表中插入新行时,ROWID可以指定为INSERT语句的一部分,也可以由数据库引擎自动指定。要手动指定ROWID,只需将其包含在要插入的值列表中即可。例如:CREATETABLEtest1(INT,bTEXT);INSERTINTOtest1(rowid,a,b)VALUES(123,5,'hello');如果在插入时没有指定ROWID,或者指定的ROWID的值为NULL,则一个适当的ROWID。通常的算法是给新创建的行一个ROWID,该ROWID比插入前表中最大的ROWID大1。如果表最初为空,则使用1的ROWID。如果最大的ROWID等于可能的最大整数(9223372036854775807),数据库引擎随机开始随机选择正候选ROWID,直到找到之前未使用过的ROWID.如果经过合理次数的尝试后仍未找到未使用的ROWID,则插入操作将失败并出现SQLITE_FULL错误。如果没有显式插入负的ROWID值,自动生成的ROWID值将始终大于零。只要您从不使用最大的ROWID值,并且您不删除具有最大ROWID的表中的条目,上述通用ROWID选择算法将生成单调递增的唯一ROWID。如果您删除行或创建具有最高可能ROWID的行,则在创建新行时可能会重复使用先前删除的行的ROWID,并且新创建的ROWID可能不会严格按升序排列。3.AUTOINCREMENT关键字如果列类型是INTEGERPRIMARYKEYAUTOINCREMENT,则使用稍微不同的ROWID选择算法。为新行选择的ROWID至少比同一表中先前存在的最大ROWID大1。如果表之前从未包含任何数据,则使用ROWID1。如果之前已插入最大可能的ROWID,则不允许新的INSERT,并且任何插入新行的尝试都将失败并出现SQLITE_FULL错误。仅考虑来自先前已提交事务的ROWID值。回滚的ROWID值将被忽略,可以重复使用。SQLite在内部使用名为“sqlite_sequence”的内部表来跟踪最大的ROWID。每当创建包含AUTOINCREMENT列的普通表时,都会自动创建和初始化sqlite_sequence表。可以使用普通的UPDATE、INSERT和DELETE语句修改sqlite_sequence表的内容。但是对该表的修改可能会破坏AUTOINCREMENT密钥生成算法。在进行此类更改之前,请确保您知道自己在做什么。sqlite_sequence表不跟踪与UPDATE语句关联的ROWID更改,仅跟踪INSERT语句。AUTOINCREMENT关键字实现的行为与默认行为略有不同。使用AUTOINCREMENT,具有自动选择的ROWID的行保证具有以前从未被同一数据库中的同一表使用过的ROWID。并且自动生成的ROWID保证单调递增。这些是某些应用程序中的重要属性。但是,如果您的应用程序不需要这些属性,您应该保留默认行为,因为使用AUTOINCREMENT需要对插入的每一行执行额外的工作,从而导致INSERT运行速度稍慢。请注意,“单调递增”并不意味着ROWID总是递增1。一种是通常的增量。但是,如果插入由于(例如)唯一性约束而失败,则失败插入尝试的ROWID可能不会在后续插入中重用,从而导致ROWID序列中出现间隙。AUTOINCREMENT保证自动选择的ROWID会增加,但不保证它们是连续的。因为AUTOINCREMENT关键字更改了ROWID选择算法的行为,所以AUTOINCREMENT不允许在WITHOUTROWID表或除INTEGERPRIMARYKEY以外的任何表列上使用。任何对WITHOUTROWID表或INTEGERPRIMARYKEY列以外的列使用AUTOINCREMENT的尝试都会导致错误。