AliSQL propose le moteur Sequence pour simplifier la récupération des valeurs de séquence.
Introduction
Les systèmes de base de données persistants nécessitent souvent une valeur unique strictement croissante pour divers cas d'utilisation, tels que les clés primaires métier sur un nœud unique, les identifiants globalement uniques dans un système distribué ou le contrôle d'idempotence entre plusieurs systèmes. Les différentes bases de données proposent des méthodes d'implémentation variées. Par exemple, MySQL fournit l'attribut AUTO_INCREMENT, tandis qu'Oracle et SQL Server proposent des objets SEQUENCE.
Dans les bases de données MySQL, l'utilisation de AUTO_INCREMENT peut s'avérer peu pratique si vous souhaitez encapsuler une valeur unique avec des informations supplémentaires, comme une date ou un ID utilisateur. En pratique, différentes solutions de contournement sont employées :
Générez les valeurs de séquence depuis une application ou un proxy. Toutefois, la gestion de l'état côté application complexifie la mise à l'échelle horizontale (scale-out et scale-in).
Générez les valeurs de séquence à partir d'une table simulée dans la base de données. Cette méthode requiert un intergiciel (middleware) pour encapsuler et simplifier la logique de récupération des valeurs uniques.
Le moteur Sequence est conçu pour offrir une compatibilité maximale avec les méthodes utilisées par d'autres bases de données.
Le moteur Sequence implémente l'interface du moteur de stockage MySQL, mais il s'appuie sur un moteur de stockage existant, tel qu'InnoDB ou MyISAM, pour stocker les données persistantes. Cette approche garantit la compatibilité avec des outils tiers comme XtraBackup. Le moteur Sequence est donc un moteur logique.
Le moteur Sequence accède aux objets Sequence via l'interface Sequence Handler pour gérer l'incrémentation NEXTVAL et la gestion du cache. Il transmet ensuite les requêtes au moteur de stockage de la table de base sous-jacente pour l'accès final aux données.
Prérequis
Votre instance doit exécuter l'une des versions suivantes :
RDS for MySQL 8.4
RDS for MySQL 8.0 avec une version mineure du moteur 20190816 ou ultérieure
RDS for MySQL 5.7 avec une version mineure du moteur 20210430 ou ultérieure
RDS for MySQL 5.6 avec une version mineure du moteur 20170901 ou ultérieure
Cette fonctionnalité n'est pas prise en charge sur les instances RDS Enterprise Edition.
Limitations
Les séquences ne prennent pas en charge les sous-requêtes ni les jointures.
Utilisez
SHOW CREATE TABLEpour consulter la structure d'une séquence.Vous ne pouvez pas spécifier le moteur Sequence lors de la création d'une table. Les tables de séquence doivent être créées exclusivement à l'aide de la syntaxe décrite dans la section Création d'une séquence.
Création d'une séquence
CREATE SEQUENCE [IF NOT EXISTS] <database_name>.<sequence_name>
[START WITH <constant>]
[MINVALUE <constant>]
[MAXVALUE <constant>]
[INCREMENT BY <constant>]
[CACHE <constant> | NOCACHE]
[CYCLE | NOCYCLE]
;
Les paramètres entre crochets ([]) sont facultatifs.
Le tableau suivant décrit les paramètres.
Paramètre | Description |
START WITH | Valeur de départ de la séquence. |
MINVALUE | Valeur minimale de la séquence. |
MAXVALUE | Valeur maximale de la séquence. Remarque Si vous spécifiez NOCYCLE, l'erreur suivante s'affiche lorsque la valeur maximale est atteinte : |
INCREMENT BY | Pas d'incrémentation entre les valeurs consécutives de la séquence. |
CACHE/NOCACHE | Taille du cache. Pour de meilleures performances, vous pouvez définir une taille de cache importante. Toutefois, en cas de redémarrage de l'instance, les valeurs inutilisées dans le cache sont perdues. |
CYCLE/NOCYCLE | Indique si la séquence peut redémarrer à partir de MINVALUE une fois épuisée. Valeurs possibles :
|
Exemple :
create sequence s
start with 1
minvalue 1
maxvalue 9999999
increment by 1
cache 20
cycle;
Pour garantir la compatibilité avec les sauvegardes créées à l'aide de mysqldump, vous pouvez également créer une séquence en créant une table de séquence et en y insérant un enregistrement initial. Exemple :
CREATE TABLE schema.sequence_name ( `currval` bigint(21) NOT NULL COMMENT 'current value',
`nextval` bigint(21) NOT NULL COMMENT 'next value',
`minvalue` bigint(21) NOT NULL COMMENT 'min value',
`maxvalue` bigint(21) NOT NULL COMMENT 'max value',
`start` bigint(21) NOT NULL COMMENT 'start value',
`increment` bigint(21) NOT NULL COMMENT 'increment value',
`cache` bigint(21) NOT NULL COMMENT 'cache size',
`cycle` bigint(21) NOT NULL COMMENT 'cycle state',
`round` bigint(21) NOT NULL COMMENT 'already how many round'
) ENGINE=Sequence DEFAULT CHARSET=latin1;
INSERT INTO schema.sequence_name VALUES(0,0,1,9223372036854775807,1,1,10000,1,0);
COMMIT;
Définition de la table de séquence
Une séquence est stockée dans une table. Vous pouvez consulter sa définition en exécutant la commande SHOW CREATE TABLE. Exemple :
SHOW CREATE TABLE schema.sequence_name;
CREATE TABLE schema.sequence_name (
`currval` bigint(21) NOT NULL COMMENT 'current value',
`nextval` bigint(21) NOT NULL COMMENT 'next value',
`minvalue` bigint(21) NOT NULL COMMENT 'min value',
`maxvalue` bigint(21) NOT NULL COMMENT 'max value',
`start` bigint(21) NOT NULL COMMENT 'start value',
`increment` bigint(21) NOT NULL COMMENT 'increment value',
`cache` bigint(21) NOT NULL COMMENT 'cache size',
`cycle` bigint(21) NOT NULL COMMENT 'cycle state',
`round` bigint(21) NOT NULL COMMENT 'already how many round'
) ENGINE=Sequence DEFAULT CHARSET=latin1
Syntaxe de requête
Les séquences prennent en charge les syntaxes de requête suivantes :
-
SELECT nextval(<sequence_name>),currval(<sequence_name>) FROM <sequence_name>;RemarqueApplicable à RDS for MySQL 8.4, 8,0 et 5,7.
-
SELECT <sequence_name>.currval, <sequence_name>.nextval FROM dual;RemarqueApplicable à RDS for MySQL 8.4, 8,0, 5,7 et 5,6.
Exemple :
mysql> SELECT test.currval, test.nextval from dual;
+--------------+--------------+
| test.currval | test.nextval |
+--------------+--------------+
| 24 | 25 |
+--------------+--------------+
1 row in set (0.03 sec)
Pour une séquence nouvellement créée, vous devez appeler NEXTVAL une fois afin de l'initialiser avant de pouvoir l'interroger. Sinon, l'erreur Sequence 'xxx' is not yet defined in current session s'affiche.
Exemple d'appel à NEXTVAL :
SELECT <sequence_name>.nextval FROM dual;