Отказ от ответственности: использование последовательности является единственным масштабируемым и эффективным способом создания уникальных чисел.
Сказав это, можно реализовать собственный генератор последовательностей. Единственная ситуация, в которой есть смысл, - это если вам нужно генерировать числа без пропусков. Если у вас нет такого требования, используйте последовательность.
Вам нужна одна таблица, в которой хранятся значения последовательностей. Я обычно использую одну таблицу со строкой для каждого «генератора», который позволяет избежать дорогостоящих блокировок таблиц.
create table seq_generator
(
entity varchar(30) not null primary key,
seq_value integer default 0 not null
);
insert into seq_generator (entity) values ('testsequence');
Затем создайте функцию для увеличения значения последовательности:
create or replace function next_value(p_entity varchar)
returns integer
as
$$
update seq_generator
set seq_value = seq_value + 1
where entity = lower(p_entity)
returning seq_value;
$$
language sql;
Для получения следующего значения последовательности, например, внутри вставки:
insert into some_table
(id, ...)
values
(next_value('testsequence'), ...);
Или сделать его значением по умолчанию:
create table some_table
(
id integer not null primary key default next_value('testsequence'),
...
);
UPDATE увеличивает и блокирует строку в одном операторе, возвращая новое значение для последовательности. Если вызывающая транзакция фиксируется, обновление до seq_generator
также будет зафиксировано. Если вызывающая транзакция откатывается, обновление также откатывается.
Если вторая транзакция вызывает next_value()
для того же объекта, она должна ждать, пока первая транзакция не завершится или не откатится.
Таким образом, доступ к генератору сериализуется через эту функцию. Только одна транзакция за раз может сделать это.
Если вам нужна вторая последовательность без пропусков, просто вставьте новую строку в таблицу `seq_generator '.
Это серьезно повлияет на производительность при использовании в среде, которая выполняет много одновременных вставок.
Причина only , которая могла бы оправдать это, является юридическим требованием иметь номер без пробелов. В любом другом случае вы должны действительно использовать последовательность Postgres.