Повсеместный SQL повторно использует удаленный первичный ключ - PullRequest
0 голосов
/ 02 июля 2018

Недавно я столкнулся с очень странным поведением PSQL (v11):

Если я создаю таблицу со столбцом идентификаторов, добавляю несколько записей, а затем удаляю последнюю строку, ключ этих строк будет повторно использован!

create table "MyTable" (id identity not null, name varchar(50));

insert into "MyTable" (name) values ('Row 1');
insert into "MyTable" (name) values ('Row 2');
insert into "MyTable" (name) values ('Row 3');

select * from "MyTable"

пока все хорошо

          id   name                                              
 ===========   ============
           1   Row 1                                             
           2   Row 2                                             
           3   Row 3

затем, когда я удаляю "Строка 3"

delete from "MyTable" where id = 3;

и добавьте новую строку

insert into "MyTable" (name) values ('Row 4');

Я удивлен, получив

         id   name                                              
===========   ==============
          1   Row 1                                             
          2   Row 2                                             
 !!! ---> 3   Row 4

Есть ли способ изменить конфигурацию сервера на , предотвратить это поведение . Я также был бы рад любому другому предложению создать надежно уникальное целое число в распространяющемся SQL.

1 Ответ

0 голосов
/ 02 июля 2018

В соответствии с документацией Autoincrement ( здесь ), это, кажется, ожидаемое поведение. В частности, в документации сказано:

Если вы указываете, что хотите, чтобы механизм базы данных назначил следующее значение путем ввода нулевого (0) значения при вставке или обновлении, база данных просто находит наибольшее число, добавляет 1 и вставляет итоговое значение. Поскольку наибольшее число равно 2 в данном примере, следующее значение автоинкремента будет равно 3. Единственный способ предотвратить такое поведение при использовании автоинкремента - указать значение на вставке.

Если вы действительно хотите что-то уникальное, вы можете использовать UNIQUEIDENTIFIER, описанный в документации здесь .
Вот пример:

create table "MyTable" (id identity not null, gid UNIQUEIDENTIFIER default newid(),  name varchar(50));

insert into "MyTable" (name) values ('Row 1');
insert into "MyTable" (name) values ('Row 2');
insert into "MyTable" (name) values ('Row 3');

select * from "mytable";
delete from "MyTable" where id = 3;
insert into "MyTable" (name) values ('Row 4');
select * from "mytable";

И результаты:

<<<<<<<<<<<<<<<<<<<<<<<<
         id   gid                                    name                                              
===========   ====================================   ==================================================
          1   1F74A3E5-6EFC-4382-81DA-94F58710AD73   Row 1                                             
          2   B5FEFA7A-F85B-486A-A7CA-9615EAD1A601   Row 2                                             
          3   E327B2CF-D01D-4039-BB83-CAD966C72131   Row 3                                             


<<<<<<<<<<<<<<<<<<<<<<<<
         id   gid                                    name                                              
===========   ====================================   ==================================================
          1   1F74A3E5-6EFC-4382-81DA-94F58710AD73   Row 1                                             
          2   B5FEFA7A-F85B-486A-A7CA-9615EAD1A601   Row 2                                             
          3   66F0E55C-52CF-4183-87EE-2C0FDD6E45B6   Row 4                                             
...