Quand on crée une donnée en informatique, un utilisateur, une commande, un fichier,
il faut lui attribuer un identifiant unique. C'est grâce à lui qu'on peut la retrouver
sans confusion parmi des millions d'autres.
La solution la plus simple est un compteur. Le premier utilisateur porte le numéro 1,
le deuxième le numéro 2, et ainsi de suite. C'est ce que font la plupart des
bases de données par défaut.
Mais dès qu'on a plusieurs systèmes qui créent des données en même temps, plusieurs
serveurs, plusieurs bases, des applications mobiles qui fonctionnent hors ligne,
le compteur se met à poser problème. Deux systèmes peuvent parfaitement donner
le même numéro à deux choses différentes.
Le principe
Un UUID (Universally Unique Identifier) résout ce problème en produisant des identifiants
si longs et si imprévisibles qu'il est statistiquement impossible d'en générer deux
identiques, même sans aucune coordination entre les systèmes.
Un UUID ressemble à ça :
f47ac10b-58cc-4372-a567-0e02b2c3d479
Ce sont 32 caractères hexadécimaux, les chiffres de 0 à 9 et les lettres de a à f,
répartis en cinq groupes séparés par des tirets pour la lisibilité. Si le mot
hexadécimal ne te dit rien, le chapitre
Binaire et hexadécimal t'expliquera d'où
viennent ces lettres au milieu des chiffres.
Chaque caractère hexadécimal code 4 bits, donc un UUID pèse 128 bits en tout.
Ça représente environ 340 milliards de milliards de milliards de milliards de valeurs
possibles. Quelques bits servent à indiquer la version et le format, il en reste
largement assez pour que le risque de doublon soit négligeable.
Pour donner un ordre de grandeur, il faudrait générer un milliard d'UUID par seconde pendant environ quatre-vingt-cinq ans pour n'avoir qu'une chance sur deux de tomber sur un doublon. En pratique, la vraie cause de collision n'est jamais la statistique, c'est un générateur mal implémenté ou une source de hasard défaillante.
Les versions
Il existe plusieurs façons de fabriquer un UUID, appelées "versions". Le format est normalisé, et le premier caractère du troisième groupe indique justement la version employée. Dans l'exemple ci-dessus, ce caractère est un 4.
- UUID v4 : entièrement tiré au hasard. C'est de loin la version la plus utilisée. Simple, rapide, et il ne révèle rien sur son origine ni sur sa date de création.
- UUID v1 : basé sur l'heure et sur l'adresse matérielle de la carte réseau de la machine. Il permet un tri chronologique, mais il expose des informations sur la machine qui l'a généré, ce qui a déjà servi à identifier l'auteur d'un fichier.
- UUID v3 et v5 : calculés à partir d'un texte, via un hash. Le même texte donnera toujours le même UUID, ce qui est pratique pour dériver un identifiant stable à partir d'une donnée existante.
- UUID v7 : le plus récent. Il place un horodatage en tête, suivi de hasard. Il combine donc le tri chronologique et l'unicité, et il s'impose peu à peu comme le choix par défaut pour les nouveaux projets.
Les versions 6, 7 et 8 ont été officialisées en 2024 par une mise à jour de la norme, signe que le sujet est resté vivant longtemps après la première spécification, qui remonte aux années 1990.
Pourquoi c'est utile
Les UUID sont partout dans le développement moderne.
- Les applications distribuées : plusieurs serveurs créent des données en parallèle et chacun génère ses identifiants sans avoir à se synchroniser avec les autres. Dans une architecture en microservices, c'est un confort considérable.
- Le mode hors ligne : une application mobile peut créer une commande dans le train, sans réseau, avec son identifiant définitif. Au retour de la connexion, elle envoie la donnée telle quelle, sans avoir à renuméroter quoi que ce soit.
- Les liens de partage : quand tu partages un document en ligne, l'URL contient un identifiant impossible à deviner. Avec un compteur, il suffirait de remplacer le 41 par 42 pour lire le document du voisin.
- L'échange entre systèmes : quand deux applications s'envoient des données, les UUID garantissent qu'aucun identifiant de l'une n'entrera en conflit avec celui de l'autre.
Un UUID imprévisible n'est pas pour autant un mot de passe. Il finit dans les journaux du serveur, dans l'historique du navigateur et dans les URL partagées par copier-coller. Un contenu réellement confidentiel doit être protégé par une véritable authentification, pas par la seule difficulté de deviner son identifiant.
Les inconvénients
Les UUID ne sont pas gratuits.
- La lisibilité : "f47ac10b-58cc-4372-a567-0e02b2c3d479" est nettement moins pratique que "42" quand tu débogues un incident ou que tu dictes une référence à un collègue au téléphone.
- La taille : un UUID occupe 16 octets sous forme binaire, contre 4 octets pour un entier classique, et jusqu'à 36 caractères s'il est bêtement stocké sous forme de texte. Multiplié par des millions de lignes et par tous les index qui le référencent, ça finit par peser.
- Les performances : les index de base de données aiment les valeurs qui arrivent dans l'ordre. Les UUID v4, totalement aléatoires, s'insèrent un peu partout dans l'index et le fragmentent, ce qui dégrade les écritures sur les grosses tables. C'est précisément le problème que corrige la version 7 avec son horodatage en tête.
- La fausse bonne idée du tout-UUID : une table de référence qui contient quinze pays n'a aucun besoin d'un identifiant distribué.
Les alternatives
L'UUID n'est pas la seule réponse au problème. D'autres formats visent le même objectif avec des compromis différents.
- Les identifiants courts : des chaînes plus compactes, pensées pour tenir dans une URL lisible, très utilisées par les raccourcisseurs de liens.
- Les identifiants séquentiels distribués : un numéro composé d'un horodatage et d'un numéro de machine, popularisé par les grandes plateformes sociales. Il reste triable et compact, au prix d'une petite coordination pour attribuer les numéros de machine.
- L'approche mixte : garder un compteur interne rapide pour la base de données et exposer un UUID public dans les URL et les API. C'est souvent le meilleur des deux mondes.
Dès qu'un système doit fonctionner à grande échelle, en environnement distribué ou hors ligne, les identifiants séquentiels montrent vite leurs limites et l'UUID devient la réponse évidente. Pour une application modeste avec une seule base de données, le bon vieux compteur reste parfaitement respectable.