Nie wierzę, że istnieje prosty sposób, który jest tak prosty jak zwykłe sekwencje, ponieważ:
- Sekwencja przechowuje tylko jeden strumień liczb (następna wartość itp.). Potrzebujesz jednego dla każdej partycji.
- Sekwencje mają specjalną obsługę, która pomija bieżącą transakcję (aby uniknąć sytuacji wyścigu). Trudno jest to powtórzyć na poziomie SQL lub PL/pgSQL bez użycia sztuczek takich jak dblink.
- Właściwość kolumny DEFAULT może używać prostego wyrażenia lub wywołania funkcji, takiego jak
nextval('myseq')
; ale nie może odnosić się do innych kolumn, aby poinformować funkcję, z którego strumienia powinna pochodzić wartość.
Możesz zrobić coś, co działa, ale prawdopodobnie nie będzie to proste. Rozwiązując kolejno powyższe problemy:
- Użyj tabeli do przechowywania następnej wartości dla wszystkich partycji, ze schematem takim jak
multiseq (partition_id, next_val)
. -
Napisz
multinextval(seq_table, partition_id)
funkcja wykonująca coś takiego:- Utwórz nową transakcję niezależną od bieżącej transakcji (jednym ze sposobów na zrobienie tego jest dblink; wierzę, że inne języki serwerów mogą to zrobić łatwiej).
- Zablokuj tabelę wymienioną w
seq_table
. - Zaktualizuj wiersz, w którym identyfikator partycji to
partition_id
, o zwiększonej wartości. (Lub wstaw nowy wiersz o wartości 2, jeśli nie istnieje.) - Zatwierdź tę transakcję i zwróć poprzedni przechowywany identyfikator (lub 1).
-
Utwórz wyzwalacz wstawiania w tabeli projektów, który używa wywołania
multinextval('projects_table', NEW.Project_ID)
do wstawiania.
Sam nie korzystałem z tego całego planu, ale próbowałem czegoś podobnego dla każdego kroku z osobna. Przykłady multinextval
funkcja i wyzwalacz mogą być dostarczone, jeśli chcesz spróbować tego...