PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment créer une séquence partitionnée PostgreSQL ?

Je ne crois pas qu'il existe un moyen aussi simple que les séquences régulières, car :

  1. Une séquence ne stocke qu'un seul flux de nombres (valeur suivante, etc.). Vous en voulez un pour chaque partition.
  2. Les séquences ont un traitement spécial qui contourne la transaction en cours (pour éviter la condition de concurrence). Il est difficile de répliquer cela au niveau SQL ou PL/pgSQL sans utiliser des astuces comme dblink.
  3. La propriété de colonne DEFAULT peut utiliser une expression simple ou un appel de fonction comme nextval('myseq'); mais il ne peut pas faire référence à d'autres colonnes pour informer la fonction de quel flux la valeur doit provenir.

Vous pouvez faire quelque chose qui fonctionne, mais vous ne penserez probablement pas que c'est simple. Résoudre les problèmes ci-dessus tour à tour :

  1. Utilisez une table pour stocker la valeur suivante pour toutes les partitions, avec un schéma tel que multiseq (partition_id, next_val) .
  2. Ecrire un multinextval(seq_table, partition_id) fonction qui fait quelque chose comme ceci :

    1. Créer une nouvelle transaction indépendante de la transaction en cours (une façon de procéder consiste à utiliser dblink ; je pense que d'autres langages de serveur peuvent le faire plus facilement).
    2. Verrouiller la table mentionnée dans seq_table .
    3. Mettre à jour la ligne où l'ID de partition est partition_id , avec une valeur incrémentée. (Ou insérez une nouvelle ligne avec la valeur 2 s'il n'y en a pas.)
    4. Valider cette transaction et renvoyer l'identifiant stocké précédent (ou 1).
  3. Créez un déclencheur d'insertion sur votre table de projets qui utilise un appel à multinextval('projects_table', NEW.Project_ID) pour les insertions.

Je n'ai pas utilisé tout ce plan moi-même, mais j'ai essayé quelque chose de similaire à chaque étape individuellement. Exemples de multinextval fonction et le déclencheur peuvent être fournis si vous voulez tenter cela...