SQLite Autoincrement特性

摘要

  1. AUTOINCREMENT会使用额外的CPU、内存和磁盘空间,如不是特别需要尽量不要使用。
  2. 类型为INTEGER PRIMARY KEY的列会被作为rowid(WITHOUT ROWID表除外),并且是一个8字节有符号整数。
  3. 执行INSERT操作时如果未提供rowid,会自动分配一个未使用的整数,通常是大于当前使用的最大rowid,不论该列是否赋予了AUTOINCREMENT特性。
  4. AUTOINCREMENT关键字出现在INTEGER PRIMARY KEY之后,该特性会改变表的rowid分配算法,不会重复使用之前删掉的rowid值。

背景

rowid会被分配一个表内唯一有符号整数(WITHOUT ROWID表除外)。

通过 "rowid","rowid ","oid"可以访问rowid列,或者使用被作为rowid列的INTEGER列名称。

插入新记录时,即可以明确指定一个rowid值,也可以不提供,系统分自动分配。

复制代码
CREATE TABLE test1(a INT, b TEXT);
INSERT INTO test1(rowid, a, b) VALUES(123, 5, 'hello');

如果在插入记录时未指定rowid或指定了一个NULL值,系统会自动分配一个rowid。默认是分配一个比最后一次插入时分配的rowid大的值,从1开始。如果达到最大值(9223372036854775807),则会扫描表并使用一个未使用的rowid。如果未找到可用值则报错SQLITE_FULL。如果未显式插入一个负的rowid则自动分配的rowid永远是正值。

常规算法是只要未达到最大值则单调递增rowid。如果显式指定了最大值,下次分配时将使用之前删除的值,在这种情况下分配的rowid不会是严格递增的。

AUTOINCREMENT关键字

带有AUTOINCREMENT特性的INTEGER PRIMARY KEY列,其自增算法会与rowid的分配算法稍有不同。仍然从1开始分配,但如果达到孙最大值,下次插入时会报错SQLITE_FULL,而不会重复使用之前删除的值,除非上一个分配id的事务操作被回滚,这个值会被使用到下一次插入操作。

SQLite内部使用一个名称为sqlite_sequence的内部表存储自增字段的值,该表会在创建一个带有AUTOINCREMENT特性的表的时候自动创建。该表可以通过UPDATE、INSERT和DELETE语句直接修改,但不建议去操作该表。

单调递增并不一定意味着下次分配的值一定是增加1。例如在一次插入失败时,后续插入操作可能不会再使用那个插入失败时分配的id。简单概括就是不能假定该值一定比上一个分配的值大1。

在WITHOUT ROWID表中,或非INTEGER PRIMARY KEY列上面不允许使用AUTOINCREMENT特性。

原文链接:https://www.sqlite.org/autoinc.html

相关推荐
正在走向自律4 分钟前
Ubuntu系统下Python连接国产KingbaseES数据库实现增删改查
开发语言·数据库·python·ubuntu·kingbasees·ksycopg2
没有bug.的程序员39 分钟前
Redis 内存管理机制:深度解析与性能优化实践
java·数据库·redis·性能优化·内存管理机制
小蒜学长1 小时前
基于SpringBoot+Vue的健身房管理系统的设计与实现(代码+数据库+LW)
java·数据库·vue.js·spring boot·后端
失散131 小时前
分布式专题——2 深入理解Redis线程模型
java·数据库·redis·分布式·架构
DemonAvenger1 小时前
数据库迁移实战:最小化停机时间的方法与经验分享
数据库·sql·性能优化
xhbh6661 小时前
Python操作MySQL的两种姿势:原生SQL与ORM框架SQLAlchemy详解
数据库·oracle
CookieCrusher5 小时前
数据泄露危机逼近:五款电脑加密软件为企业筑起安全防线
运维·数据库·windows·安全·文件加密·数据防泄漏·dlp
这周也會开心6 小时前
SQL-窗口函数
数据库·sql
TDengine (老段)8 小时前
TDengine 时间函数 WEEKDAY() 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
TDengine (老段)8 小时前
从 ETL 到 Agentic AI:工业数据管理变革与 TDengine IDMP 的治理之道
数据库·数据仓库·人工智能·物联网·时序数据库·etl·tdengine