PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come creare una sequenza partizionata PostgreSQL?

Non credo che ci sia un modo semplice che sia facile come le sequenze regolari, perché:

  1. Una sequenza memorizza solo un flusso di numeri (valore successivo, ecc.). Ne vuoi uno per ogni partizione.
  2. 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.
  3. 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:

  1. Utilizza una tabella per memorizzare il valore successivo per tutte le partizioni, con uno schema come multiseq (partition_id, next_val) .
  2. Scrivi un multinextval(seq_table, partition_id) funzione che fa qualcosa di simile al seguente:

    1. Crea una nuova transazione indipendente dalla transazione corrente (un modo per farlo è tramite dblink; credo che altri linguaggi del server possano farlo più facilmente).
    2. Blocca la tabella menzionata in seq_table .
    3. 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.)
    4. Compila quella transazione e restituisce l'ID memorizzato precedente (o 1).
  3. 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...