Les séquences ?!? Mais qu'est ce donc ? Comment fonctionnent-elles ? Qu'est-ce que cela va nous apporter ?
Autant de questions auxquelles on tentera de répondre dans cet article.
Une séquence est une sorte de table particulière qui permet de générer un nombre proprement.
Les nombres générés proviennent d'une suite que l'on aura au préalable paramétrée dans la séquence.
Elle est habituellement utilisée pour générer des identifiants uniques pour les lignes d'une table, dans les autres SGBD on la connaît sous le nom de champ auto-incrémenté.
Il peut exister une infinité de séquences au sein d'une même base de données.
Chaque séquence a ses propres caractéristiques et la génération d'un nombre n'affecte pas les autres séquence de la base.
Enfin une même table peut utiliser une ou plusieurs séquences différentes.
II. Pourquoi les utiliser ?
Lorsque l'on développe une base, il est souvent nécessaire d'avoir recours à un nombre unique comme clef primaire par exemple,
mais la gestion de ce nombre est plus complexe qu'il n'y paraît, en effet, il faut que la génération de ce nombre soit unique et ce, dans un environnement multi-utilisateurs.
Ainsi, supposons qu'une centaine de clients tentent de récupérer un nombre exactement en même temps, ils doivent recevoir chacun un nombre différent.
La séquence est une méthode sûre pour générer ces nombres.
III. Comment en créer une ?
C'est relativement simple :
CREATESEQUENCE ma_sequence;
Il existe de nombreuses options à cette commande, comme par exemple spécifier la valeur de départ (START 150), définir le pas d'incrément (INCREMENT 2), etc.
Je vous invite à lire la documentation en référence à la fin de l'article
Une séquence est implicitement créée lorsque l'on déclare la création d'une table avec une colonne de type SERIAL.
La colonne se transformera en type INTEGER mais aura une valeur par défaut à nextval('ma_sequence');
CREATETABLE ma_table (idauto SERIAL, nom VARCHAR(100));
Un message d'information nous indique que le serveur a automatiquement créé une séquence (ma_table_idauto_seq)
NOTICE: CREATE TABLE will create implicit sequence "ma_table_idauto_seq" for serial column "ma_table.idauto"
De manière général, un SERIAL implique la création d'une séquence portant le nom de la table (ma_table) concaténée du nom du champ (idauto) et du suffixe _seq
Ce qui donnera : ma_table_idauto_seq
IV. Comment est composée une séquence ?
Pour connaître le contenu d'une séquence il suffit de faire :
SELECT * FROM ma_sequence;
Champs
Type
Valeur par défaut
Informations
sequence_name
text
ma_sequence
le nom de la séquence
last_value
int8
1
Prochaine valeur retournée, ici 1
increment_by
int8
1
Le pas de l'increment est de 1
max_value
int8
2^63
Valeur maximum de la séquence : 2^63 !!!!
Si cette valeur est atteinte et que is_cycledest à true,
la valeur repart à min_value.
min_value
int8
1
Valeur minimum de la séquence : 1
cache_value
int8
1
cache spécifie comment les numéros de séquence doivent être préalloués et stockés
en mémoire pour un accès plus rapide, ici on préalloue 1 nombre.
is_cycled
bool
false
si on atteint valeurmax ou valeurmin, on autorise le générateur à boucler
V. Comment manipuler les séquences ?
Les commandes ALTER SEQUENCE ne sont disponibles qu'à partir de la version 7.4
Changer la prochaine valeur à 123 :
ALTERSEQUENCE ma_sequence RESTART WITH 123;
Changer la valeur minimum à 10 :
ALTERSEQUENCE ma_sequence MINVALUE 10;
Changer la valeur maximum à 600 :
ALTERSEQUENCE ma_sequence MAXVALUE 600;
Changer le pas de l'incrémentation à 7 :
ALTERSEQUENCE ma_sequence INCREMENT 7;
Passer la séquence en cycle :
ALTERSEQUENCE ma_presence CYCLE;
Créer une séquence avec les paramètres ci-dessous :
Il existe des fonctions pour manipuler les séquences : nextval, currval, setval
Fonction
Type de retour
Description
nextval
bigint
Ajoute INCREMENT à la valeur actuelle de la séquence et renvoit sa nouvelle valeur
currval
bigint
Dernière valeur renvoyée par nextval. Attention currval déclenche une erreur si nextval n'a pas été appelée auparavant dans la même session
setval(text,bigint)
bigint
Initialise la valeur courante de la séquence
setval(text,bigint, boolean)
bigint
Initialise la valeur courante de la séquence et le drapeau is_called
Exemple d'utilisation :
SELECT setval('ma_sequence',456); -- on initialise ma_sequence à 456 SELECT nextval('ma_sequence'); -- on incremente la prochaine valeur, en retour nous obtenons 457SELECT currval('ma_sequence'); -- on demande la valeur courante, en retour nous obtenons 457
VI. Comment supprimer une séquence ?
Tout simplement avec la commande :
DROPSEQUENCE ma_table_idauto_seq;
Si l'on tente de supprimer une séquence utilisée par une table, postgresql renvoi le message d'erreur suivant :
ERROR: cannot drop sequence ma_table_idauto_seq because table ma_table column idauto requires it
ASTUCE : You may drop table ma_table column idauto instead.
Postgres refuse tout simplement de supprimer la séquence car ma_table en a besoin.
Cependant il nous indique que l'on peut supprimer la colonne idauto de la table.
Lorsque l'on supprime la colonne, la séquence qui y était liée est automatiquement supprimée.
ALTERTABLE ma_table DROP COLUMN idauto
VII. Comment se comporte les séquences dans une transaction ?
Si dans notre transaction on utilise une séquence pour générer successivement plusieurs nombres, et qu'à la fin de la transaction on procède à un rollback, la séquence ne reviendra pas en arrière :