Quand les ordis ont commencé à vraiment se connecter entre eux, un souci tout bête mais super important est apparu : comment garantir que deux machines différentes, à l'autre bout du monde, ne vont pas générer le même identifiant ?
Imagine : deux serveurs, un à Tokyo, l'autre à Berlin, qui créent chacun de leur côté des identifiants pour des objets. S'ils génèrent le même ID par hasard — les données peuvent se mélanger, être écrasées, et tout le système peut planter.
C'est comme ça que dans les années 90, à l'époque du boom des systèmes distribués et des protocoles réseau, chez Microsoft et Open Software Foundation (OSF), est née l'idée du GUID — Globally Unique Identifier, ou identifiant globalement unique.
Le GUID (et dans la norme ISO — UUID, Universally Unique Identifier) — c'est un nombre sur 128 bits, qui ressemble à ça par exemple :
550e8400-e29b-41d4-a716-446655440000
C'est comme une empreinte digitale numérique : c'est tellement long et aléatoire que la probabilité d'une collision (deux identifiants identiques) est quasi nulle.
Il est généré à partir de :
- l'heure,
- des nombres aléatoires,
- l'adresse MAC de la machine (dans les vieilles versions),
- et même des fonctions de hash cryptographiques.
Pourquoi c'était important ? Parce que le GUID a permis de créer des identifiants uniques sans serveur central, sans coordination, sans locks ni latence. C'était un vrai sauveur pour :
- les bases de données distribuées,
- les protocoles réseau,
- les systèmes de gestion documentaire,
- et bien sûr, les API modernes.
UUID dans PostgreSQL
Le GUID/UUID est utilisé partout — de PostgreSQL aux services cloud. Ce sont les bâtisseurs invisibles du web moderne : sans eux, on ne pourrait pas connecter le monde aussi facilement.
En fait, c'est juste un très grand nombre aléatoire de 16 octets, écrit en hexadécimal. Juste un très grand entier.
Ce type de données est parfait si tu veux garantir l'unicité des valeurs à l'échelle du système, sans dépendre d'un générateur centralisé d'identifiants. C'est super utile dans les systèmes distribués ou quand les données sont créées sur plusieurs serveurs.
Pourquoi ne pas utiliser juste INTEGER ?
On pourrait se dire, pourquoi s'embêter avec UUID alors qu'on peut juste utiliser un nombre auto-incrémenté comme identifiant ? Voyons ça :
Unicité globale : Si ta base tourne sur plusieurs serveurs, garantir l'unicité d'un INTEGER devient galère. Avec UUID, ce souci disparaît.
Sécurité et masquage des données : Un UUID est bien plus dur à deviner qu'un numéro séquentiel. Ça limite les risques de fuite d'infos via des IDs prévisibles (genre /users/1, /users/2).
Systèmes distribués : Si les données sont générées à différents endroits du système, un INTEGER auto-incrémenté ne marche pas sans une synchro compliquée.
Un autre avantage du UUID — c'est un standard, supporté dans plein de langages et de systèmes de stockage.
Avantages d'utiliser UUID
Les gros plus :
- Unicité : tu es sûr que l'identifiant est unique, même si les données sont créées sur différents serveurs ou systèmes.
- Flexibilité : tu peux t'en servir pour les clés primaires, étrangères, et plein d'autres trucs.
- Scalabilité : super pratique avec des bases distribuées.
Mais le UUID a aussi ses inconvénients :
- Taille :
UUIDprend plus de place en mémoire (16 octets) qu'unINTEGER(4 octets). - Lisibilité : c'est moins facile à lire et à retenir.
Générer un UUID dans PostgreSQL
Fonction intégrée gen_random_uuid()
Depuis PostgreSQL 13, il y a la fonction intégrée gen_random_uuid() pour générer des UUID aléatoires. Cette fonction te renvoie un identifiant unique que tu peux utiliser comme valeur pour une colonne de type UUID.
Exemple :
SELECT gen_random_uuid();
Résultat :
d17fc23b-22e5-4fcb-bf86-1b4c766d77b7
Vérifie que l'extension pgcrypto est installée (pour PSQL 1-12)
Dans les vieilles versions de PostgreSQL (avant la 13), la fonction gen_random_uuid() est dispo après avoir installé l'extension pgcrypto. Si au taf on t'oblige à l'utiliser, tu peux t'en sortir avec cette commande :
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
Ça te permet d'utiliser la génération d'UUID aléatoires.
Utiliser UUID comme clé étrangère
Le UUID est super pratique pour faire des liens entre les tables. Imaginons que tu as une table users :
| id | name | |
|---|---|---|
| d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 | Alice | alice@example.com |
| a1d3e15a-abc1-4b51-a320-2d4c859f7467 | Bob | bob@example.com |
| 3c524998-5c24-4e73-836d-a4c6bb3cafcd | Charlie | charlie@example.com |
Créer la table orders
On va créer une table orders, où user_id sera une clé étrangère qui pointe sur id dans la table users.
| order_id | user_id | order_date |
|---|---|---|
| 1a5b7d9c-b1a2-4f8e-9e7a-0a1111111111 | d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 | 2024-10-15 10:00:00 |
| 2b6c8e0d-c2b3-5a9f-af8b-1b2222222222 | a1d3e15a-abc1-4b51-a320-2d4c859f7467 | 2024-10-15 10:05:00 |
| 3c7d9f1e-d3c4-6baf-bc9c-2c3333333333 | 3c524998-5c24-4e73-836d-a4c6bb3cafcd | 2024-10-15 10:10:00 |
| 4d8eaf2f-e4d5-7cb0-cdab-3d4444444444 | d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 | 2024-10-15 10:15:00 |
| 5e9fb030-f5e6-8dc1-debc-4e5555555555 | a1d3e15a-abc1-4b51-a320-2d4c859f7467 | 2024-10-15 10:20:00 |
Le champ user_id est lié au champ id de la table users, ce qui permet de faire le lien entre les users et leurs commandes.
Sélection de données avec JOIN
Voyons comment les données sont reliées dans les tables users et orders :
SELECT
u.id AS user_id,
u.name,
o.order_id,
o.order_date
FROM users u
JOIN orders o ON u.id = o.user_id;
Résultat :
| user_id | name | order_id | order_date |
|---|---|---|---|
| d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 | Alice | a1d3e15a-abc1-4b51-a320-2d4c859f7467 | 2024-10-20 12:34:56 |
Scénarios typiques d'utilisation de UUID
Identifiants pour users et commandes : dans les systèmes distribués, où les données peuvent venir de différentes sources.
Tags pour API : UUID est souvent utilisé dans les REST API pour identifier les entités.
Synchronisation globale des données : par exemple, quand les données sont collectées depuis plusieurs serveurs.
Erreurs courantes et particularités
Essayer de générer un UUID à la main : mieux vaut utiliser les fonctions intégrées comme gen_random_uuid() pour éviter les boulettes.
Surutilisation : n'utilise pas UUID là où un INTEGER auto-incrémenté suffit. Genre dans des tables locales qui ne seront jamais scalées.
Taille : UUID prend plus de place, ce qui peut impacter les perfs des requêtes, surtout avec les index.
GO TO FULL VERSION