Я не верю, что есть простой способ, который так же прост, как регулярные последовательности, потому что:
- В последовательности хранится только один поток чисел (следующее значение и т. Д.). Вы хотите один для каждого раздела.
- Последовательности имеют специальную обработку, которая обходит текущую транзакцию (чтобы избежать условия гонки). Трудно воспроизвести это на уровне SQL или PL / pgSQL без использования таких трюков, как dblink.
- Свойство столбца DEFAULT может использовать простое выражение или вызов функции, например
nextval('myseq')
; но он не может ссылаться на другие столбцы, чтобы сообщить функции, из какого потока должно поступить значение.
Вы можете сделать что-то, что работает, но вы, вероятно, не будете думать, что это просто. Решение указанных проблем по очереди:
- Используйте таблицу для хранения следующего значения для всех разделов со схемой, подобной
multiseq (partition_id, next_val)
.
Напишите функцию multinextval(seq_table, partition_id)
, которая выполняет что-то вроде следующего:
- Создание новой транзакции, независимой от текущей транзакции (один из способов сделать это - через dblink; я полагаю, что некоторые другие языки сервера могут сделать это проще).
- Блокировка таблицы, упомянутой в
seq_table
.
- Обновите строку, в которой идентификатор раздела равен
partition_id
, с увеличенным значением. (Или вставьте новую строку со значением 2, если ее еще нет.)
- Передать эту транзакцию и вернуть предыдущий сохраненный идентификатор (или 1).
Создайте триггер вставки в таблице проектов, в котором для вставки используется вызов multinextval('projects_table', NEW.Project_ID)
.
Я не использовал весь этот план сам, но я пробовал что-то похожее на каждый шаг в отдельности. Примеры функции multinextval
и триггера могут быть предоставлены, если вы хотите попробовать это ...