Non credo che ci sia un modo semplice che sia facile come le sequenze regolari, perché:
- Una sequenza memorizza solo un flusso di numeri (valore successivo, ecc.). Ne vuoi uno per ogni partizione.
- Le sequenze hanno una gestione speciale che ignora la transazione corrente (per evitare la race condition). È difficile replicarlo a livello SQL o PL/pgSQL senza usare trucchi come dblink.
- La proprietà della colonna DEFAULT può utilizzare una semplice espressione o una chiamata di funzione come
nextval('myseq')
; ma non può fare riferimento ad altre colonne per informare la funzione da quale stream dovrebbe provenire il valore.
Puoi creare qualcosa che funzioni, ma probabilmente non lo penserai semplice. Affrontare a turno i problemi di cui sopra:
- Utilizza una tabella per memorizzare il valore successivo per tutte le partizioni, con uno schema come
multiseq (partition_id, next_val)
. -
Scrivi un
multinextval(seq_table, partition_id)
funzione che fa qualcosa di simile al seguente:- Crea una nuova transazione indipendente dalla transazione corrente (un modo per farlo è tramite dblink; credo che altri linguaggi del server possano farlo più facilmente).
- Blocca la tabella menzionata in
seq_table
. - Aggiorna la riga in cui l'ID partizione è
partition_id
, con un valore incrementato. (Oppure inserisci una nuova riga con valore 2 se non ce n'è una esistente.) - Compila quella transazione e restituisce l'ID memorizzato precedente (o 1).
-
Crea un trigger di inserimento sulla tabella dei tuoi progetti che utilizzi una chiamata a
multinextval('projects_table', NEW.Project_ID)
per inserimenti.
Non ho utilizzato l'intero piano da solo, ma ho provato qualcosa di simile per ogni passaggio individualmente. Esempi del multinextval
funzione e il trigger possono essere forniti se si desidera tentare questo...