I. Que sont les séquences ?▲
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 :
CREATE
SEQUENCE 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');
CREATE
TABLE
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 :
ALTER
SEQUENCE ma_sequence RESTART WITH
123
;
Changer la valeur minimum à 10 :
ALTER
SEQUENCE ma_sequence MINVALUE 10
;
Changer la valeur maximum à 600 :
ALTER
SEQUENCE ma_sequence MAXVALUE
600
;
Changer le pas de l'incrémentation à 7 :
ALTER
SEQUENCE ma_sequence INCREMENT
7
;
Passer la séquence en cycle :
ALTER
SEQUENCE ma_presence CYCLE;
Créer une séquence avec les paramètres ci-dessous :
CREATE
SEQUENCE ma_sequence MINVALUE 10
MAXVALUE
600
INCREMENT
7
CYCLE;
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 457
SELECT
currval
(
'ma_sequence'
)
; -- on demande la valeur courante, en retour nous obtenons 457
VI. Comment supprimer une séquence ?▲
Tout simplement avec la commande :
DROP
SEQUENCE 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.
ALTER
TABLE
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 :
Commande | N° généré |
---|---|
BEGIN | |
INSERT ... | 25 |
INSERT ... | 26 |
INSERT ... | 27 |
INSERT ... | 28 |
ROLLBACK | |
INSERT ... | 29 |
INSERT ... | 30 |
VIII. Documents de référence▲
http://www.postgresql.org/docs/8.0/interactive/sql-createsequence.html
http://www.postgresql.org/docs/8.0/interactive/functions-sequence.html
http://www.postgresql.org/docs/8.0/interactive/sql-altersequence.html
http://www.postgresql.org/docs/8.0/interactive/sql-dropsequence.html
IX. Remerciements▲
Je souhaite remercier GrandFather pour son aide et ses observations.