我有一个关于informix db 主键上使用的串行数据类型的快速问题。
如果我删除一行,序列号会继续计数还是会重新调整已删除的行?
那么如果当前行是序列号 5,我删除序列号为 3 的数字行,下一个值为 6 并继续进行吗?现在被删除的3号序列号是永远丢失不能再使用了吗?
SERIAL、SERIAL8 或 BIGSERIAL 使用的计数器单调递增,直到回绕。删除的值被简单地删除。如果您插入一个大于计数器的字面值,则会调整计数器,以便下一个插入的值更大:
CREATE TABLE s (s SERIAL(2) NOT NULL PRIMARY KEY, v VARCHAR(20) NOT NULL);
INSERT INTO s(s,v) VALUES(0, "Row 2");
INSERT INTO s(s,v) VALUES(0, "Row 3");
INSERT INTO s(s,v) VALUES(0, "Row 4");
INSERT INTO s(s,v) VALUES(0, "Row 5");
DELETE FROM s WHERE s = 3;
INSERT INTO s(s,v) VALUES(0, "Row 6");
INSERT INTO s(s,v) VALUES(8, "Row 8"); -- Skip 7
INSERT INTO s(s,v) VALUES(0, "Row 9");
SELECT * FROM s ORDER BY s;
这会产生结果:
2 Row 2
4 Row 4
5 Row 5
6 Row 6
8 Row 8
9 Row 9
所有类型的行为都相似。如果达到最大值(SERIAL 为 2^32-1,SERIAL8 和 BIGSERIAL 为 2^63-1),则计数器回零,但您可能会遇到未腾出的空间被重用且主键被拒绝的问题重复的行。一般来说,避免包装它们。(使它们回绕需要相当长的时间,尤其是 64 位计数器。)
请注意,您可以手动插入“缺失”值 - 例如 3 或 7。但是,IDS 不会为您执行此操作。
@iQ 问:
那么 Informix 在回绕时会自动重新使用未使用或已删除的序列值吗?
并不真地。该值返回到 1;如果值为 1 的行存在,则插入失败;如果没有,则成功;无论哪种方式,下一次尝试都将尝试 2。为了说明,继续上一个示例停止的地方:
INSERT INTO s(s,v) VALUES(2147483647, "Row 2,147,483,647");
INSERT INTO s(s,v) VALUES(0, "Row next") { 1 - Pass };
INSERT INTO s(s,v) VALUES(0, "Row next + 1") { 2 - Fail };
INSERT INTO s(s,v) VALUES(0, "Row next + 2") { 3 - Pass };
INSERT INTO s(s,v) VALUES(0, "Row next + 3") { 4 - Fail };
SELECT * FROM s ORDER BY s;
最终结果是:
1 Row next
2 Row 2
3 Row next + 2
4 Row 4
5 Row 5
6 Row 6
8 Row 8
9 Row 9
2147483647 Row 2,147,483,647
很明显,接下来的三个插入会失败,一个会成功,另外两个会失败,然后他们会在接下来的数十亿次插入中成功。