Qu'est-ce qu'un UUID ?
Un UUID (Universally Unique Identifier, identifiant universel unique), connu dans la terminologie Microsoft sous le nom de GUID (Globally Unique Identifier), est un nombre de 128 bits utilisé pour identifier de manière unique des informations dans les systèmes informatiques. Contrairement aux entiers à incrémentation automatique qui nécessitent une autorité centrale pour attribuer la valeur suivante, les UUID peuvent être générés indépendamment par n'importe quelle machine, à n'importe quel moment, avec une probabilité de collision astronomiquement faible.
La représentation textuelle canonique d'un UUID ressemble à ceci :
550e8400-e29b-41d4-a716-446655440000
^^^^^^^^ ^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^
temps temps ver. var. nœud
Cette chaîne avec des tirets encode 32 chiffres hexadécimaux (128 bits) dans le format xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx, où :
- M est le chiffre de version (1, 3, 4, 5 ou 7)
- N est le quartet de variante (8, 9, a ou b pour les UUID conformes à RFC 4122)
Une Brève Histoire
Le concept d'identifiant universellement unique est né à la fin des années 1980 chez Apollo Computer et Digital Equipment Corporation (DEC) dans le cadre du Système de Calcul en Réseau (NCS) et de l'Environnement de Calcul Distribué (DCE). L'objectif était de permettre aux systèmes distribués de créer des identifiants sans aucun registre central.
Microsoft a adopté ce concept pour COM/OLE et l'a appelé GUID, mais la structure sous-jacente est identique à un UUID. Les deux termes sont interchangeables en pratique.
La spécification formelle est arrivée avec RFC 4122, publiée en juillet 2005 par l'IETF. Elle a standardisé cinq versions d'UUID (v1–v5) et défini les bits de variante. Deux décennies plus tard, RFC 9562 (publiée en mai 2024) a remplacé RFC 4122 et ajouté officiellement UUID v6 et v7, qui répondent aux lacunes de performances en base de données des versions antérieures.
Structure d'un UUID : 128 Bits Expliqués
Un UUID fait toujours exactement 128 bits (16 octets). Formatée en chaîne, elle fait 36 caractères (32 chiffres hexadécimaux + 4 tirets).
Champ Bits Chiffres hex Description
────────────────────────────────────────────────────────────────
time_low 32 8 32 bits bas de l'horodatage (v1)
time_mid 16 4 16 bits médians de l'horodatage (v1)
time_hi_and_version 16 4 12 bits hauts de l'horodatage + version 4 bits
clock_seq_hi_res 8 2 Bits de variante + séquence d'horloge haute
clock_seq_low 8 2 Séquence d'horloge basse
node 48 12 ID de nœud (adresse MAC en v1, aléatoire sinon)
La version est encodée dans les 4 bits les plus significatifs du champ time_hi_and_version (le 13e caractère hexadécimal). La variante est encodée dans les 2–3 bits les plus significatifs de clock_seq_hi_res (le 17e caractère hexadécimal).
Versions d'UUID Expliquées
Version 1 — Basée sur le Temps
UUID v1 combine un horodatage de 60 bits (intervalles de 100 nanosecondes depuis le 15 octobre 1582) avec l'adresse MAC de l'hôte et une séquence d'horloge.
Exemple : 6ba7b810-9dad-11d1-80b4-00c04fd430c8
Avantages : Contient des informations temporelles, permettant un tri approximatif par heure de création.
Inconvénients : Intègre l'adresse MAC, ce qui soulève des problèmes de confidentialité : cela peut révéler quand et où un UUID a été généré. Non recommandé pour les identifiants publics.
Version 2 — Sécurité DCE
UUID v2 remplace une partie de l'horodatage par un UID/GID POSIX et un identifiant de domaine. Elle est définie dans la spécification DCE 1.1 mais rarement utilisée en pratique, car elle sacrifie les garanties d'unicité pour l'intégration du domaine.
Version 3 — Basée sur le Nom (MD5)
UUID v3 génère un UUID déterministe à partir d'un UUID d'espace de noms et d'un nom en les hachant avec MD5.
Exemple : 5df41881-3aed-3515-88a7-2f4a814cf09e (espace de noms DNS + "example.com")
Cas d'usage : Identifiants stables et reproductibles pour la même ressource logique. Si l'on hache le même espace de noms et le même nom deux fois, on obtient toujours le même UUID.
Attention : MD5 est cryptographiquement faible. Préférez v5 pour les nouveaux systèmes.
Version 4 — Aléatoire (La Plus Populaire)
UUID v4 utilise 122 bits de données aléatoires cryptographiquement sécurisées (les 6 bits restants sont utilisés pour la version et la variante).
Exemple : 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
C'est de loin la version d'UUID la plus utilisée. Elle ne nécessite ni coordination, ni accès réseau, ni connaissance de l'hôte. L'aléatoire provient d'un CSPRNG (générateur de nombres pseudo-aléatoires cryptographiquement sécurisé).
Version 5 — Basée sur le Nom (SHA-1)
UUID v5 est identique dans le concept à v3 mais utilise SHA-1 à la place de MD5.
Exemple : 886313e1-3b8a-5372-9b90-0c9aee199e5d (espace de noms DNS + "example.com")
Cas d'usage : Lorsque des UUID déterministes et reproductibles sont nécessaires et qu'un hachage plus fort que MD5 est souhaité. SHA-1 n'est pas cryptographiquement sécurisé pour tous les usages, mais sa résistance aux collisions est significativement meilleure que MD5.
Version 7 — Ordonnée par le Temps (Recommandée pour les Bases de Données)
UUID v7 est la vedette de RFC 9562. Elle intègre un horodatage Unix de 48 bits en millisecondes dans les bits les plus significatifs, rendant l'UUID k-triable : les UUID générés ultérieurement se trient après les UUID générés antérieurement.
Exemple : 018e8f5a-2b3c-7d4e-8f9a-0b1c2d3e4f50
Les 12 premiers caractères hexadécimaux (018e8f5a-2b3c) encodent l'horodatage en millisecondes. Le reste est aléatoire. Cela rend v7 idéal comme clé primaire de base de données : elle conserve l'unicité globale de v4 tout en étant ordonnée par insertion, ce qui réduit considérablement la fragmentation de l'index B-tree.
Probabilité de Collision : Le Problème des Anniversaires
UUID v4 utilise 122 bits d'aléatoire. La probabilité de collision peut être estimée à l'aide de la formule du problème des anniversaires :
p(n) ≈ 1 − e^(−n²/2N)
où N = 2^122 ≈ 5,32 × 10^36 (nombre total d'UUID possibles).
Pour avoir une probabilité de 50% d'au moins une collision, il faudrait générer environ 2,71 × 10^18 (2,71 trillions) d'UUID. À un rythme de 1 milliard d'UUID par seconde, cela prendrait environ 86 ans.
Pour des fins pratiques, les collisions UUID v4 sont si improbables qu'elles peuvent être traitées comme impossibles dans toute application du monde réel.
UUID vs. IDs Auto-Incrémentés
| Fonctionnalité | UUID v4 | Auto-Incrément |
|---|---|---|
| Portée d'unicité | Globale | Locale (par table) |
| Lieu de génération | Côté client | Côté serveur |
| Prévisibilité | Non prévisible | Séquentiel |
| Sécurité URL | Oui (avec encodage) | Oui |
| Performance index BDD | Faible (aléatoire) | Excellente (séquentiel) |
| Fusion/réplication | Facile | Sujette aux conflits |
| Taille de stockage | 16 octets (binaire) | 4–8 octets |
| Lisibilité humaine | Faible | Élevée |
| Sécurité (énumération) | Sûr | Vulnérable |
Les IDs auto-incrémentés conviennent parfaitement aux applications à base de données unique sans exigences distribuées. Les UUID brillent lorsque :
- Plusieurs services ou bases de données doivent générer des IDs de manière indépendante.
- Les enregistrements peuvent être fusionnés depuis différentes sources.
- On veut éviter d'exposer des IDs séquentiels dans les URLs (attaques par énumération).
Performances en Base de Données : v4 vs. v7
Le Problème avec UUID v4 dans les Bases de Données
Parce que UUID v4 est aléatoire, chaque nouvelle ligne est insérée à une position aléatoire dans l'index B-tree. Cela provoque :
- Divisions de pages d'index — la base de données doit fréquemment diviser les pages d'index pour accueillir des insertions désordonnées.
- Thrashing de cache — les patterns d'accès aléatoires annulent le pool de tampons, causant de fréquentes lectures disque.
- Amplification d'écriture — beaucoup plus d'E/S que les insertions séquentielles.
Les benchmarks sur les grandes tables (>10 M de lignes) montrent souvent que les clés primaires UUID v4 sont 3 à 5 fois moins performantes que les clés séquentielles pour les charges de travail à forte insertion.
UUID v7 Résout Ce Problème
UUID v7 est monotoniquement croissant dans la même fenêtre de milliseconde. Les nouveaux enregistrements sont insérés à la fin ou près de la fin de l'index, comme l'auto-incrémentation. Le résultat :
- Fragmentation d'index quasi nulle.
- Utilisation optimale du pool de tampons.
- Performances d'insertion comparables à l'auto-incrémentation.
Recommandation : Utilisez UUID v7 pour tout nouveau schéma de base de données nécessitant des clés primaires globalement uniques.
Cas d'Usage dans les Systèmes Distribués
Les UUID sont l'épine dorsale de l'identité distribuée :
- Microservices : Chaque service peut générer des IDs de manière indépendante sans communiquer avec un serveur de séquences central.
- Event sourcing : Les événements obtiennent des IDs immuables qui restent uniques à travers les rediffusions et réhydratations.
- CQRS : Les commandes et requêtes peuvent être corrélées par un UUID généré côté client.
- Bases de données multi-régions : Les enregistrements créés dans différentes régions ne se heurtent jamais, rendant triviales la cohérence éventuelle et les opérations de fusion.
- Clés d'idempotence : Les APIs peuvent utiliser des UUIDs générés côté client comme clés d'idempotence pour relancer les requêtes en toute sécurité.
- Systèmes à contenu adressable : UUID v3/v5 peuvent produire des identifiants stables pour la même ressource à travers les systèmes.
ULID : Une Alternative Moderne
ULID (Universally Unique Lexicographically Sortable Identifier) est une alternative développée par la communauté à l'UUID, sûre pour les URLs par défaut et toujours triable.
| Fonctionnalité | UUID v4 | UUID v7 | ULID |
|---|---|---|---|
| Triable | Non | Oui | Oui |
| Sûr pour URL | Avec encodage | Avec encodage | Oui (Crockford Base32) |
| Composant temporel | Non | Oui (ms) | Oui (ms) |
| Standard | RFC 9562 | RFC 9562 | Spécification communautaire |
| Longueur du format | 36 chars | 36 chars | 26 chars |
| Monotone dans ms | Non | Optionnel | Oui |
Un ULID ressemble à 01ARZ3NDEKTSV4RRFFQ69G5FAV — 26 caractères, sans tirets, utilisable directement dans les URLs. Si vous avez besoin de triabilité et de sécurité URL sans vous soucier de la compatibilité RFC, ULID vaut la peine d'être considéré.
Génération d'UUID dans Différents Langages
JavaScript / TypeScript (Node.js et Navigateur)
import { v4 as uuidv4, v7 as uuidv7 } from 'uuid';
const randomId = uuidv4(); // "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
const sortableId = uuidv7(); // "018e8f5a-2b3c-7d4e-8f9a-0b1c2d3e4f50"
// crypto natif (Node 14.17+ / navigateurs modernes)
const nativeId = crypto.randomUUID(); // UUID v4
Python
import uuid
# v4 — aléatoire
print(uuid.uuid4()) # "f47ac10b-58cc-4372-a567-0e02b2c3d479"
# v5 — déterministe depuis espace de noms + nom
print(uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com'))
# "886313e1-3b8a-5372-9b90-0c9aee199e5d"
Go
import "github.com/google/uuid"
id := uuid.New() // UUID v4
v7, _ := uuid.NewV7() // UUID v7 (google/uuid v1.6+)
fmt.Println(id.String())
Java
import java.util.UUID;
UUID v4 = UUID.randomUUID();
System.out.println(v4); // "3e4666bf-d5e5-4aa7-b8ce-cefe41c7568a"
Rust
use uuid::Uuid;
let v4 = Uuid::new_v4();
let v7 = Uuid::now_v7();
println!("{}", v4);
println!("{}", v7);
Meilleures Pratiques
- Utilisez v4 pour les identifiants uniques à usage général où l'ordre n'a pas d'importance.
- Utilisez v7 pour les clés primaires de base de données pour éviter la fragmentation d'index et obtenir un ordre de tri naturel.
- Utilisez v5 pour les IDs déterministes quand vous avez besoin que la même entrée produise toujours le même UUID (par exemple, déduplication de contenu par URL).
- Évitez v1 dans les contextes sensibles à la confidentialité — elle intègre votre adresse MAC et votre heure de création.
- Stockez les UUID en binaire (16 octets) dans la base de données, pas en varchar(36), pour économiser de l'espace et améliorer les performances d'index.
- N'utilisez jamais v2 sauf si vous implémentez spécifiquement DCE Security.
- Validez les UUID en entrée aux frontières d'API pour empêcher l'injection d'identifiants malformés.
- Utilisez une bibliothèque bien testée plutôt que d'implémenter votre propre génération UUID — les sources d'entropie sont faciles à mal implémenter.
Questions Fréquemment Posées
Q : UUID et GUID sont-ils la même chose ?
R : Fonctionnellement, oui. GUID est le nom Microsoft pour le même format d'identifiant à 128 bits. La structure est identique ; seule la terminologie diffère.
Q : Deux UUID peuvent-ils être identiques ?
R : En théorie oui, mais la probabilité est négligeable pour v4. Il faudrait générer 2,71 trillions d'UUID pour avoir 50% de chances d'une seule collision. En pratique, vous ne rencontrerez jamais une collision.
Q : Quelle version d'UUID dois-je utiliser pour les clés primaires de base de données ?
R : UUID v7 est le meilleur choix. Elle est ordonnée dans le temps (bon pour les index B-tree), globalement unique et standardisée dans RFC 9562. Si votre bibliothèque ne supporte pas encore v7, utilisez un ULID ou un pattern "COMB" UUID comme solution de contournement.
Q : UUID v4 est-il suffisamment sécurisé pour être utilisé comme jeton de session ?
R : UUID v4 dispose de 122 bits d'aléatoire, ce qui est généralement suffisant. Cependant, les bibliothèques dédiées aux jetons de session peuvent utiliser légèrement plus d'entropie ou de meilleures encodages. Pour les contextes à haute sécurité, préférez un générateur de jetons dédié.
Q : Comment stocker efficacement un UUID dans une base de données SQL ?
R : Utilisez un type de colonne UUID natif si disponible (PostgreSQL, MySQL 8+), ou une colonne BINARY(16). Évitez CHAR(36) / VARCHAR(36) qui prend 2,25 fois plus d'espace et est plus lent à indexer.
Q : Quelle est la différence entre UUID v3 et v5 ?
R : Les deux sont basés sur un nom et déterministes. v3 utilise MD5 ; v5 utilise SHA-1. SHA-1 a une meilleure résistance aux collisions, donc v5 est préféré pour les nouveaux systèmes. Aucun ne doit être utilisé pour le hachage critique en matière de sécurité.
Q : UUID v7 remplace-t-il UUID v4 ?
R : Pour les clés primaires de base de données, oui — v7 est strictement meilleur. Pour d'autres cas d'usage (par exemple, clés API, jetons, IDs de corrélation) où l'ordre est sans importance, v4 reste parfaitement adapté.
Résumé
Les UUID sont une primitive fondamentale dans l'ingénierie logicielle moderne. Comprendre les différences entre les versions aide à faire les bons compromis :
- v4 — meilleur pour l'unicité générale sans coordination.
- v5 — meilleur pour les identifiants déterministes et reproductibles.
- v7 — meilleur pour les clés primaires de base de données grâce à l'ordre temporel.
Que vous construisiez un monolithe, une architecture microservices ou une base de données distribuée mondialement, les UUID fournissent un moyen éprouvé et standardisé d'identifier vos données de manière unique et sécurisée.