Informix: Что происходит, когда вы удаляете строку с первичным ключом serial / serial8?

StackOverflow https://stackoverflow.com/questions/1819040

  •  10-07-2019
  •  | 
  •  

Вопрос

У меня был быстрый вопрос о последовательных типах данных, используемых в первичном ключе в базе данных informix.

Если я удалю строку, будет ли продолжаться подсчет серийного ключа или он будет перенастроен для любых удаленных строк?

Таким образом, если текущая строка является серийной № 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

Все типы ведут себя одинаково. Если вы достигнете максимума (2 ^ 32-1 для SERIAL, 2 ^ 63-1 для SERIAL8 и BIGSERIAL), то счетчик обнулится, но у вас могут возникнуть проблемы с повторным использованием незанятых пространств, и первичный ключ отклонил повторяющиеся строки. Как правило, избегайте их оборачивать. (Чтобы их обернуть, требуется много времени, особенно 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