Ik geloof niet dat er een eenvoudige manier is die zo gemakkelijk is als gewone reeksen, omdat:
- Een reeks slaat slechts één nummerstroom op (volgende waarde, enz.). Je wilt er een voor elke partitie.
- Sequenties hebben een speciale behandeling die de huidige transactie omzeilt (om de race-conditie te vermijden). Het is moeilijk om dit op SQL- of PL/pgSQL-niveau te repliceren zonder trucjes zoals dblink te gebruiken.
- De kolomeigenschap DEFAULT kan een eenvoudige expressie of een functieaanroep gebruiken zoals
nextval('myseq')
; maar het kan niet verwijzen naar andere kolommen om de functie te informeren uit welke stream de waarde moet komen.
Je kunt iets maken dat werkt, maar je zult het waarschijnlijk niet eenvoudig vinden. Om beurten de bovenstaande problemen aanpakken:
- Gebruik een tabel om de volgende waarde voor alle partities op te slaan, met een schema zoals
multiseq (partition_id, next_val)
. -
Schrijf een
multinextval(seq_table, partition_id)
functie die zoiets als het volgende doet:- Maak een nieuwe transactie aan die onafhankelijk is van de huidige transactie (een manier om dit te doen is via dblink; ik geloof dat sommige andere servertalen dit gemakkelijker kunnen doen).
- Vergrendel de tabel vermeld in
seq_table
. - Update de rij waar de partitie-ID
partition_id
is , met een verhoogde waarde. (Of voeg een nieuwe rij in met waarde 2 als er geen bestaande is.) - Voer die transactie uit en retourneer de eerder opgeslagen id (of 1).
-
Maak een invoegtrigger op uw projectentabel die een aanroep gebruikt naar
multinextval('projects_table', NEW.Project_ID)
voor invoegingen.
Ik heb dit hele plan zelf niet gebruikt, maar ik heb iets soortgelijks geprobeerd voor elke stap afzonderlijk. Voorbeelden van de multinextval
functie en de trigger kan worden verstrekt als u dit wilt proberen...