L'attribut AUTO_INCREMENT de MySQL génère des valeurs uniques uniquement au sein d'une seule table. Lorsque vous avez besoin d'identifiants globalement uniques et strictement croissants dans un système distribué, ou si vous souhaitez utiliser des objets SEQUENCE de style Oracle dans MySQL, le moteur Sequence Engine d'AliSQL offre une solution native. Cette approche élimine le recours à des compteurs côté application ou à des intergiciels supplémentaires.
Fonctionnement
Le moteur Sequence Engine est un moteur logique qui s'appuie sur un moteur de stockage existant (InnoDB ou MyISAM). Il ne stocke pas directement les données ; il délègue la persistance à la table de base sous-jacente tout en utilisant le gestionnaire de séquence (Sequence Handler) pour gérer l'état et la mise en cache des séquences.
Appelez
NEXTVALpour incrémenter le compteur de séquence et récupérer la valeur suivante.Appelez
CURRVALpour lire la dernière valeur renvoyée à la session actuelle sans incrémenter le compteur.
Étant donné que les séquences sont prises en charge par des moteurs de stockage standard, elles sont compatibles avec des outils tiers tels que XtraBackup et mysqldump.
Versions prises en charge
Le moteur Sequence Engine nécessite l'une des versions mineures suivantes du moteur :
| Version MySQL | Version mineure minimale du moteur |
|---|---|
| MySQL 8.0 | 20190816 |
| MySQL 5.7 | 20210430 |
| MySQL 5.6 | 20170901 |
RDS Enterprise Edition n'est pas pris en charge.
Limitations
Les sous-requêtes et les requêtes JOIN ne sont pas prises en charge sur les séquences.
Pour créer une séquence, utilisez l'instruction
CREATE SEQUENCE. Vous ne pouvez pas spécifierENGINE=Sequencedans une instructionCREATE TABLE.Inspectez la définition d'une séquence à l'aide de
SHOW CREATE TABLE.
Créer 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];
Lors de l'exécution de l'instruction précédente, vous devez configurer les paramètres indiqués entre crochets ([]).
Le tableau suivant décrit chaque paramètre.
| Paramètre | Description |
|---|---|
START WITH |
Valeur de départ de la séquence. |
MINVALUE |
Valeur minimale. Sert de point de réinitialisation lorsque CYCLE est activé. |
MAXVALUE |
Valeur maximale. Lorsque cette valeur est atteinte avec l'option NOCYCLE, la séquence s'arrête et renvoie l'erreur suivante : ERROR HY000: Sequence 'db.seq' has been run out. |
INCREMENT BY |
Pas entre les valeurs consécutives. |
CACHE / NOCACHE |
Nombre de valeurs à pré-allouer en mémoire. Un cache plus important améliore le débit. Si l'instance redémarre, les valeurs mises en cache non utilisées sont perdues. |
CYCLE / NOCYCLE |
Indique s'il faut revenir à MINVALUE une fois que MAXVALUE est atteint. |
Exemple : Créez une séquence cyclique commençant à 1 et revenant à zéro après 9 999 999.
CREATE SEQUENCE s
START WITH 1
MINVALUE 1
MAXVALUE 9999999
INCREMENT BY 1
CACHE 20
CYCLE;
Compatibilité avec mysqldump
Si vous souhaitez utiliser l'extension mysqldump pour sauvegarder votre instance RDS, vous pouvez créer une séquence sous forme de table classique et insérer manuellement une ligne initiale :
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;
Interroger une séquence
Deux formes de syntaxe sont prises en charge. Utilisez celle qui correspond à votre version de MySQL.
| Syntaxe | Versions prises en charge |
|---|---|
SELECT nextval(<sequence_name>), currval(<sequence_name>) FROM <sequence_name>; |
MySQL 8.0, MySQL 5.7 |
SELECT <sequence_name>.currval, <sequence_name>.nextval FROM dual; |
MySQL 8.0, MySQL 5.7, MySQL 5.6 |
La forme FROM dual reproduit la syntaxe des séquences Oracle (sequence_name.nextval) et constitue la seule option disponible sur MySQL 5.6.
Exemple : Récupérez les valeurs actuelle et suivante pour une séquence nommée test.
mysql> SELECT test.currval, test.nextval FROM dual;
+--------------+--------------+
| test.currval | test.nextval |
+--------------+--------------+
| 24 | 25 |
+--------------+--------------+
1 row in set (0.03 sec)
Exemple : Appelez NEXTVAL deux fois pour observer l'incrémentation.
mysql> SELECT test.nextval FROM dual;
+--------------+
| test.nextval |
+--------------+
| 25 |
+--------------+
mysql> SELECT test.nextval FROM dual;
+--------------+
| test.nextval |
+--------------+
| 26 |
+--------------+
Avant d'interroger une nouvelle séquence pour la première fois dans une session, appelezNEXTVALpour l'initialiser. Si vous ignorez cette étape, l'erreur suivante est renvoyée :Sequence 'xxx' is not yet defined in current session.
SELECT <sequence_name>.nextval FROM dual;
Structure de la table de séquence
Les séquences sont stockées dans le moteur de table de base sous-jacent. Exécutez SHOW CREATE TABLE pour inspecter la définition actuelle et la disposition des colonnes d'une séquence :
SHOW CREATE TABLE schema.sequence_name;
Résultat :
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
Lacunes et perte de données
Les séquences ne garantissent pas l'absence de lacunes dans les valeurs.
Les redémarrages d'instance entraînent la suppression des valeurs conservées dans le cache. N'utilisez pas les séquences pour une logique métier nécessitant une série de nombres contigus et ininterrompus (comme les numéros de facture réglementaires).
Utilisez les séquences pour les clés primaires de substitution ou les identifiants globaux uniques (GUID) dans les systèmes distribués, où la présence de lacunes est acceptable.