CodeGym /Cours /SQL SELF /Génération d'identifiants uniques

Génération d'identifiants uniques

SQL SELF
Niveau 16 , Leçon 0
Disponible

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 GUIDGlobally 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 : UUID prend plus de place en mémoire (16 octets) qu'un INTEGER (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 email
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.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION