我对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

所有类型的行为都相似。如果达到最大值(SERIAL8为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   

显然,接下来的三个插入将失败,一个会成功,另外两个会失败,然后他们会成功接下来的几十亿个插入。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top