【问题标题】:Informix: What happens when you delete a row with serial/serial8 primary key?Informix:当您删除带有 serial/serial8 主键的行时会发生什么?
【发布时间】:2009-11-30 10:37:03
【问题描述】:

我有一个关于informix db 主键上使用的串行数据类型的快速问题。

如果我删除一行,序列号会继续计数还是会重新调整已删除的行?

所以如果当前行是序号5,我删除序号为3的数字行,下一个值是6并继续吗?现在删掉的3号连载是不是永远丢失了不能再用了?

【问题讨论】:

标签: sql informix


【解决方案1】:

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   

显然,接下来的三个插入会失败,一个会成功,另外两个会失败,然后在接下来的数十亿次插入中它们会成功。

【讨论】:

  • +1 我刚刚了解到 VALUES 中的 0 并不总是意味着 0 :)。我通常使用表格 INSERT INTO s(v) VALUES('Row 8'); (跳过串行列)请注意,如果您在 INSERT 值中指定它,其他数据库(例如 PostgreSQL)会将 0 插入串行列。使用 " 而不是 ' 也是 Informix 特有的。
  • 是的 - Informix SERIAL 的行为一直如此,因为在基于 SQL 的 Informix 版本之前。自古以来,单引号与双引号(两者都有效)也是 Informix 的一部分。
  • informix 回绕时是否会自动重新使用未使用或已删除的序列值?
  • @iQ:当它回绕时,Informix 尝试一次尝试使用下一个回绕值。如果失败(值仍在使用中),则语句失败。不好 - 如果你有一个滑动窗口,比如 1000 万行,那么当发生换行时,在低数字处有很多空白空间;否则,就会出现问题。
猜你喜欢
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-19
  • 2018-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多