sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo crear una secuencia particionada de PostgreSQL?

No creo que haya una manera simple que sea tan fácil como las secuencias regulares, porque:

  1. Una secuencia almacena solo un flujo de números (siguiente valor, etc.). Quiere uno para cada partición.
  2. Las secuencias tienen un manejo especial que pasa por alto la transacción actual (para evitar la condición de carrera). Es difícil replicar esto a nivel de SQL o PL/pgSQL sin utilizar trucos como dblink.
  3. La propiedad de la columna DEFAULT puede usar una expresión simple o una llamada de función como nextval('myseq'); pero no puede hacer referencia a otras columnas para informar a la función de qué flujo debe provenir el valor.

Puedes hacer algo que funcione, pero probablemente no lo creas simple. Abordar los problemas anteriores a su vez:

  1. Utilice una tabla para almacenar el siguiente valor para todas las particiones, con un esquema como multiseq (partition_id, next_val) .
  2. Escribe un multinextval(seq_table, partition_id) función que hace algo como lo siguiente:

    1. Cree una nueva transacción independiente de la transacción actual (una forma de hacerlo es a través de dblink; creo que otros lenguajes de servidor pueden hacerlo más fácilmente).
    2. Bloquear la tabla mencionada en seq_table .
    3. Actualice la fila donde la identificación de la partición es partition_id , con un valor incrementado. (O inserte una nueva fila con el valor 2 si no existe ninguna).
    4. Confirme esa transacción y devuelva la identificación almacenada anterior (o 1).
  3. Cree un disparador de inserción en su tabla de proyectos que use una llamada a multinextval('projects_table', NEW.Project_ID) para inserciones.

No he usado todo este plan yo mismo, pero he intentado algo similar para cada paso individualmente. Ejemplos del multinextval se puede proporcionar la función y el activador si desea intentar esto...