如何在sqlite中使用一个序列号来操作所有的表格

8
当我创建SQLite数据库中的表时,每个表都会自动创建单独的序列。然而,我想在我的SQLite数据库中为所有表使用一个序列,并且需要设置该序列的最小和最大值(例如min=10000max=999999)(minmax表示序列的起始值和序列可以增加的最大值)。我知道这可以在Oracle数据库中完成,但不知道如何在SQLite中完成。是否有任何方法可以做到这一点?

1
@muistooshort,我使用“SQLite数据库浏览器”检查了SQLite数据库。在我的数据库中,每个表都有单独的不同序列,存储在“sqlite_sequence”表中。 - Bishan
2个回答

6

很遗憾,你不能这样做:SQLite会自动为每个表创建一个特殊的sqlite_sequence服务表中的序列。

即使你以某种方式强制将单个序列作为所有表的源,它也不会按你期望的方式工作。例如,在PostgreSQL或Oracle中,如果你将序列设置为值1,但表已经填充了值12等的行,任何尝试使用该序列作为源插入新行的操作都会因唯一约束冲突而失败。

然而,在SQLite中,如果你手动重置序列,可以使用以下内容:

UPDATE sqlite_sequence SET seq = 1 WHERE name = 'mytable'

如果你已经拥有了行 1,2,3 ... ,尝试插入新的行将不会失败,而是自动分配该序列适当自增列的最大现有值,以便它可以一直增加。

请注意,您可以使用此技巧为序列分配起始值,但无法使其停止增长到某个值(除非您使用其他方式监视它)。


如果列使用自动增量,则不会发生重复,因为下一次您将使用序列,SQLite将生成一个数字,该数字是表中的最大值+1。我不确定这是否仅适用于主键或具有唯一约束的列,但通常对于自动增量列来说是这种情况。 - RobMcZag
@RobMcZag:这正是我所说的-在SQLite中,如果当前值已经存在于表中,序列将自动分配下一个可能的值。当前算法是max+1。 - mvp
是的,但是要尝试泛化。在你的例子中,你将序列设置为1,但是你的行中有id=1。我想指出的是,在SQLite中,无论如何都会得到max+1,即使你将序列设置为表中没有的数字,所以人们可能会认为该数字可用。 - RobMcZag

1
首先,这是一个不好的想法。
数据库查询的性能取决于可预测性,通过调整索引序列,您会引入偏移量,这会混淆数据库引擎。
然而,为了实现这一点,您可以尝试确定最低的序列号,该序列号高于或等于任何现有的序列号:
SELECT MAX(seq) FROM sqlite_sequence

每次插入查询后都需要执行此操作,然后更新所有表的所有序列:

UPDATE sqlite_sequence SET seq=determined_max

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接