Outils de développement · Générateur UUID
ULID, Snowflake, KSUID et UUIDv7 : comparaison des identifiants triables
· Contexte
uuid cryptographie API du navigateur
Les UUID aléatoires ne sont pas triés par heure de création, donc plusieurs formats mettent un horodatage en premier. Cet article compare ULID, Snowflake, KSUID et UUIDv7 sur la disposition, la taille, la monotonie et la compatibilité.
Les identifiants aléatoires et l'index qui les déteste : le problème que les identifiants ordonnés dans le temps résolvent
Les UUID v4 aléatoires dispersent les points d'insertion sur une clé primaire B-tree à mesure que de nouveaux enregistrements arrivent, provoquant des fractionnements de pages et une réorganisation. Les insertions à des positions aléatoires dégradent les performances d'écriture et augmentent considérablement la fragmentation du disque. Les bases de données à haut débit tolèrent ce coût – le prix d’identifiants véritablement indépendants et non coordonnés – mais le coût est réel. Si vous avez besoin de trier les UUID par heure de création, vous pouvez améliorer considérablement les caractéristiques de l'index en ajoutant un préfixe d'horodatage. Plusieurs formats ont vu le jour : ULID, Snowflake, KSUID et RFC 9562 v7. Chacun fait des compromis différents en termes de taille (caractères 26 à 128 bits), de précision d'horodatage (de secondes à nanosecondes), de compatibilité UUID et de savoir si la coordination du générateur d'ID nécessite une centralisation. Les tests de base de données montrent que les performances d'insertion s'améliorent considérablement.
ULID — un horodatage 48 bits en millisecondes plus 80 bits aléatoires en 26 caractères Crockford base32, avec une option monotone
ULID (Universally Unique Lexicographically Sortable Identifier) code un horodatage 48-bit milliseconde et une charge utile aléatoire 80-bit en 26 caractères de Crockford base32. La représentation textuelle est triée correctement dans l'ordre lexicographique, ce qui rend les ULID adaptés aux systèmes où l'ordre des horodatages et la lisibilité sont importants : traitement des journaux, traçage distribué, microservices où les identifiants doivent être facilement lisibles dans une sortie accessible à l'homme. ULID propose une variante monotone dans laquelle plusieurs identifiants générés dans la même milliseconde incrémentent la partie aléatoire au lieu de se répéter, garantissant que même les rafales d'identification rapides maintiennent un ordre de génération strict. Le compromis est que l'ULID n'est pas un UUID : il ne rentre pas dans une colonne de base de données standard 128-bit UUID sans conversion de codage. La précision ULID couvre environ 8925 ans.
Snowflake — ID 64 bits à partir d'un horodatage, d'un ID de travailleur et d'une séquence, ainsi que la coordination dont ils ont besoin
Snowflake est un identifiant 64-bit conçu à l'origine par Twitter, structuré comme un horodatage 41-bit milliseconde, un identifiant de travailleur 10-bit et un numéro de séquence 12-bit. L'horodatage 41 bits couvre environ 69 ans et déborde dans 2106, nécessitant une coordination d'époque et une planification de migration. L'ID de travailleur distingue les identifiants générés par différents serveurs ou processus : chaque générateur Snowflake doit connaître son propre ID de travailleur unique sans entrer en conflit avec les autres. Snowflake fait 64 bits au lieu de 128, ce qui en fait la moitié de la taille d'un UUID, plus rapide à indexer et plus efficace en matière de stockage par identifiant. Il trie par heure et ID de travailleur, utile pour acheminer les demandes ou les journaux par source. L’inconvénient est opérationnel : chaque générateur doit se voir attribuer un identifiant de travailleur, les horloges doivent rester synchronisées.
KSUID — un horodatage en secondes avec une charge utile aléatoire importante, triée en octets
KSUID (K-Sortable Unique Identifier) est un identifiant 128 bits composé d'un 32-bit Unix second timestamp et d'une charge utile aléatoire 96-bit, généralement codée sous forme de 27 caractères base62. Le format peut être trié par ordre lexicographique et la partie aléatoire est cryptographiquement valable pour sa taille. KSUID est moins largement adopté que ULID ou Snowflake mais offre une sémantique distincte : l'horodatage est facilement décodé en une seconde lisible par l'homme (utile dans les journaux et le débogage), et la partie aléatoire 96 bits est suffisamment grande pour que plusieurs KSUID générés dans la même seconde aient effectivement une probabilité de duplication nulle sans coordination de séquence. Contrairement à Snowflake, KSUID ne nécessite aucune coordination des identifiants de travailleur ni allocation centrale. KSUID fonctionne en secondes plutôt qu'en millisecondes, donc plusieurs ID en une seconde sont triés de manière aléatoire, sauf si vous implémentez une logique supplémentaire.
UUIDv7 — la réponse normative qui s'adapte aux colonnes et outils uuid existants
RFC 9562 v7 est un identifiant 128 bits composé d'un horodatage Unix 48 bits en millisecondes, de 12 bits d'une précision inférieure à la milliseconde (utilisable comme compteur de séquence) et de 62 bits aléatoires tous combinés. Il trie correctement à la fois sous forme de chaîne lexicographique et sous forme d'octets 128 bits dans les bases de données. Surtout, il s'agit d'un UUID valide : il définit le quartet de version sur 7 et les bits de variante sur la norme RFC 9562, ce qui le rend compatible avec tous les outils, colonnes de base de données et API qui gèrent les UUID. Aucune conversion d'encodage n'est nécessaire et l'infrastructure UUID existante ne nécessite aucune modification. Si plusieurs identifiants v7 sont générés dans la même milliseconde, la RFC 9562 recommande d'utiliser le champ inférieur à la milliseconde comme compteur monotone plutôt que comme bits aléatoires. La V7 représente un choix pragmatique pour maintenir la compatibilité UUID.
Monotonie en une milliseconde : comment chaque format gère les rafales et pourquoi cela est important pour commander des garanties
La monotonie est la propriété selon laquelle si deux événements se produisent dans un ordre observable, leurs identifiants se comparent dans le même ordre. Avec une granularité de l'ordre de la milliseconde sur le matériel moderne, plusieurs événements se produisent régulièrement au cours du même tick d'horloge, de sorte que tout schéma d'identification triable doit gérer correctement l'ordre inférieur à la milliseconde. ULID propose un mode monotone explicite où la partie aléatoire s'incrémente au lieu d'être randomisée. Snowflake comprend un numéro de séquence 12 bits qui s'incrémente en une milliseconde. KSUID ne dispose pas d'un mécanisme intégré, donc les événements inférieurs à la seconde sont triés de manière aléatoire à moins qu'une logique supplémentaire ne soit ajoutée. La RFC 9562 v7 recommande d'utiliser le champ inférieur à la milliseconde comme compteur monotone. Si votre système génère des milliers d'UUID par seconde, la monotonie en une milliseconde a un impact significatif sur l'ordre des requêtes.
Ce que cela ne couvre pas : les tests de débit, qui dépendent du matériel et de la langue ; le post reste qualitatif
Les tests de débit et les données de performances ne sont pas inclus car ils dépendent fortement de l'architecture matérielle, de l'implémentation du langage, du moteur de base de données et de la stratégie de mise en cache. Les caractéristiques de performances de la base de données varient considérablement selon que vous mesurez les insertions aléatoires, les requêtes de plage, la surcharge d'index ou le débit total sous une charge de production réaliste. Le message reste qualitatif, comparant les formats conceptuellement en fonction de leur conception plutôt que de fournir des chiffres spécifiques à l'environnement qui pourraient être trompeurs. L'évaluation des performances dans le monde réel nécessite des tests dans votre propre environnement avec votre propre charge de travail, votre propre base de code et vos contraintes opérationnelles. L’analyse comparative de différents formats d’identification est un exercice précieux.
À retenir : la compatibilité décide souvent : le générateur ToolAcre produit des UUID aléatoires ; utilisez sa vérification bien formée pour confirmer qu'un UUIDv7 de votre bibliothèque est analysé comme un UUID
La compatibilité décide souvent du format à choisir. Si votre schéma de base de données nécessite déjà des colonnes UUID, la v7 est la réponse moderne à la possibilité de tri sans quitter l'écosystème UUID. Si vous construisez un nouveau système avec des types d’ID personnalisés, ULID offre une représentation de texte plus petite et des avantages de précision à la milliseconde. Si vous avez besoin d'un stockage 64 bits et pouvez gérer la coordination des ID des travailleurs grâce à une allocation centralisée, Snowflake est un choix éprouvé dans les systèmes à volume élevé. Le compromis fondamental se situe entre la compatibilité standard (choisissez la v7) et les propriétés alternatives telles que une taille plus petite (Snowflake) ou la lisibilité base32 (ULID). Faites des choix basés sur les contraintes du système et les décisions de l’écosystème.