PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como criar uma sequência particionada do PostgreSQL?


Eu não acredito que exista uma maneira simples que seja tão fácil quanto as sequências regulares, porque:
  1. Uma sequência armazena apenas um fluxo de números (próximo valor, etc.). Você quer um para cada partição.
  2. As sequências têm tratamento especial que ignora a transação atual (para evitar a condição de corrida). É difícil replicar isso no nível SQL ou PL/pgSQL sem usar truques como dblink.
  3. A propriedade da coluna DEFAULT pode usar uma expressão simples ou uma chamada de função como nextval('myseq'); mas não pode se referir a outras colunas para informar a função de qual stream o valor deve vir.

Você pode fazer algo que funcione, mas provavelmente não achará simples. Resolvendo os problemas acima, por sua vez:
  1. Use uma tabela para armazenar o próximo valor para todas as partições, com um esquema como multiseq (partition_id, next_val) .

  2. Escreva um multinextval(seq_table, partition_id) função que faz algo como o seguinte:
    1. Crie uma nova transação independente da transação atual (uma maneira de fazer isso é através do dblink; acredito que algumas outras linguagens de servidor possam fazer isso mais facilmente).
    2. Bloqueie a tabela mencionada em seq_table .
    3. Atualize a linha em que o ID da partição é partition_id , com um valor incrementado. (Ou insira uma nova linha com valor 2 se não houver uma existente.)
    4. Confirme essa transação e retorne o ID armazenado anterior (ou 1).

  3. Crie um gatilho de inserção em sua tabela de projetos que use uma chamada para multinextval('projects_table', NEW.Project_ID) para inserções.

Eu mesmo não usei esse plano inteiro, mas tentei algo semelhante para cada etapa individualmente. Exemplos do multinextval função e o gatilho pode ser fornecido se você quiser tentar isso ...