表级别定义的PRIMARY KEY约束是否保证AUTOINCREMENT并且没有值重用?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (92)

请考虑以下表定义:

CREATE TABLE names (
    id INTEGER,
    name TEXT NOT NULL,
    PRIMARY KEY (id)
)

它是否保证id每个新插入都会自动递增,并且删除行的值不会被重用?

我查阅了Sqlite3的文档,但找不到答案。

提问于
用户回答回答于

id INTEGER PRIMARY KEY 在它自己的保证(需要)一个唯一的整数值,并且如果没有专门分配值将提供一个,直到最高值达到64位有符号整数(9223372036854775807)的最高允许值,之后可以找到并应用未使用的值。

随着AUTOINCREMENT有保证(如果不是回避)总是提供更高的价值,但如果9223372036854775807达到的,而不是分配一个未使用的数量将导致一个SQLITE_FULL错误。这是唯一的区别,从分配的数字的角度来看。

两者都不能保证单调增加的价值。

没有AUTOINCREMENT,计算/算法相当于

  • 1 + max(rowid),如果该值大于9223372036854775807,则尝试查找未使用且因此值较低的值。
    • 我没有看到任何人遇到过未分配随机未使用值的情况。

使用AUTOINCREMENT,计算/算法是

  • 1 + max(rowid)或SELECT seq FROM sqlite_sequence中的较大者WHERE name ='the_table_name_the_rowid_is_being_assigned_to',如果该值大于9223372036854775807则为SQLITE_FULL ERROR。
  • 注意,无论哪种方式,最大rowid可能是最终没有插入的行,因此可能存在间隙。

答案可能是最好的:最好/建议仅将id列用于其预期目的,即有效识别行而不是处理其他数据要求的方法,如果这样做,则没有必要用于AUTOINCREMENT(有开销

简言

它是否保证id将自动递增

没有

已删除行的值不会被重用?

NO对于给定的代码

适用于: -

CREATE TABLE names (id INTEGER PRIMARY KEY AUTOINCREMENT name TEXT NOT NULL)

再次NO,如果达到9223372036854775807那么将导致SQLITE_FULL错误,否则为YES

因此,当插入9223372036854775807第一行时,真正的AUTOINCREMENT才真正相关(如果id按预期/预期使用)。

也许考虑以下几点: -

DROP TABLE IF EXISTS table1;
DROP TABLE IF EXISTS table2;

CREATE TABLE IF NOT EXISTS table1 (id INTEGER PRIMARY KEY, somecolumn TEXT);
CREATE TABLE IF NOT EXISTS table2 (id INTEGER PRIMARY KEY AUTOINCREMENT, somecolumn TEXT);

INSERT INTO table1 VALUES (9223372036854775807,'blah'); 
INSERT INTO table2 VALUES (9223372036854775807,'blah');
INSERT INTO table1 (somecolumn) VALUES(1),(2),(3); 
SELECT * FROM table1;
INSERT INTO table2 (somecolumn) VALUES(1),(2),(3);

这创建了两个相似的表,唯一的区别是使用AUTOINCREMENT。每个插入的行都具有id列的最高允许值。

然后尝试插入3行,其中id将由SQLite分配。

在没有AUTOINCREMENT的情况下将3行插入到表中,但在使用AUTOINCREMENT时不会插入任何行。按照 :

CREATE TABLE IF NOT EXISTS table1 (id INTEGER PRIMARY KEY, somecolumn TEXT)
> OK
> Time: 0.098s


CREATE TABLE IF NOT EXISTS table2 (id INTEGER PRIMARY KEY AUTOINCREMENT, somecolumn TEXT)
> OK
> Time: 0.098s


INSERT INTO table1 VALUES (9223372036854775807,'blah')
> Affected rows: 1
> Time: 0.094s


INSERT INTO table2 VALUES (9223372036854775807,'blah')
> Affected rows: 1
> Time: 0.09s


INSERT INTO table1 (somecolumn) VALUES(1),(2),(3)
> Affected rows: 3
> Time: 0.087s


SELECT * FROM table1
> OK
> Time: 0s


INSERT INTO table2 (somecolumn) VALUES(1),(2),(3)
> database or disk is full
> Time: 0s

table1的SELECT结果(由于随机性可能不同)是: -

热门问答

关于文字鉴别的违法的问题?

ritchiechen

腾讯 · 后台开发工程师 (已认证)

推荐

请使用 `try catch` 捕获异常,查看堆栈信息

在服务器启动的项目,怎么才能关掉控制台,项目不会自动也关闭?

推荐
比较常用的有两种方式 1. 把程序添加到Linux的后台服务中,详见https://blog.csdn.net/zj15527620802/article/details/90056946 2. 将应用程序放在某容器中启动,如nohup等,详见https://blog.csdn....... 展开详请

怎么实现存储桶设置私有读写的时候,可以直接访问图片,和复制临时链接一直的功能?

幻象丛林RESTful 服务开发者
推荐
临时链接是携带了签名参数,在后台复制时是自动算好的,可以在签名有效期内临时访问对象。 如果需要自己实现的话可以调用GET Object接口,携带Authorization签名。 GET /<ObjectKey> HTTP/1.1 Host: <BucketName-APPID>....... 展开详请

调用人脸变化接口,为什么一直错误?

zqfan

腾讯 · 高级工程师 (已认证)

推荐

请尽量使用SDK吧,能够有效避免签名错误。

这个签名错误一般是由于timestamp参数取值和标准时间相差过大引起的,常见的是客户端本地时间没有和互联网时间同步,此外timestamp要求是到秒,而不是毫秒。请阅读API文档里调用方式相关的文档。

腾讯会议,电脑版,召开会议提示发生异常(错误码:-161)),是什么问题?

推荐已采纳
-161是媒体服务器连接超时,造成该问题的原因可能有: 1. 网络异常 2. 开启了V** 3. 网络有防火墙或上网策略控制 4. 安装风行加速器进行LSP劫持 可以按照上述信息排查一下。... 展开详请

为什么服务器经常掉线,我进控制台看是运行的状态,但就是访问不了网站,ssh也登录不了,重启后才行?

我是预言家你有freestyle么
推荐
经常掉线可能是因为长时间不操作,闲置时间过长所以服务器自动断开连接 解决此问题的方法: 方法一: vi /etc/ssh/sshd_config配置文件,修改ClientAliveCountMax(单位为分钟)为想要的值! 修改完成并保存后,执行命令:service sshd r...... 展开详请

所属标签

扫码关注云+社区

领取腾讯云代金券