Quels sont les avantages d'un UUID ?
Qu'est ce qu'un UUID ?
Un UUID (ou universally unique identifier) est un identifiant de 32 caractères (36 en comptant ses tirets). Un UUID ressemble à ça :
- 8f14a65f-3032-42c8-a196-1cf66d11b930
Chaque caractère d'un UUID est simplement la forme hexadécimale (base 16) d'une valeur, chaque caractère est donc la représentation de 4bits. On peut donc en déduire qu'un UUID fait donc 128bits. Alors si les UUIDs sont si bien, si "parfaits" et si unique, pourquoi n'utilisons pas tous les UUIDs et dans toutes les bases de données. Pourquoi le UUID n'est pas LA référence quand on cherche a créer un identifiant dans une base de donnée ?
C'est exactement la question que je me suis posé il y a quelques semaines. Je me suis mis au défi de développer une application qui permettrait à des utilisateurs de stocker leurs fichiers par l'intermédiaire d'un site internet (dans le style Google Drive ou Dropbox). J'ai alors eu une idée, pourquoi chaque fichier ne serait pas représenté par un UUID dans ma base de donnée. Au final si un UUID est si unique, pourquoi pas l'utiliser à la place d'un compteur incrémental ?
Un UUID est-il vraiment unique ?
Alors, c'est sûr que c'est bizarre, si un UUID est généré de manière aléatoire, comment s'assurer que pour chaque uuid généré, ce dernier ne soit déjà présent dans ma base de donnée ? Cette question est normale et est même primordiale. Au final, si on vous demande de piocher une boule dans un sac de boules, vous avez bien une probabilité, faible, de repiocher la même boule. Et si on fait cette opération 10 fois, 100 fois, 1000 fois, cette probabilité ne fait qu'augmenter.
Alors comment est composé un UUID ?
Un UUID, même si généré "aléatoirement" est généré suivant une certaine logique : Les 122 bits sont générés de manière aléatoire et les 6bits sont appelés "bits de variance" et ne varient pas (contrairement à leur nom).
L'UUID v4 est composé de 128 bits divisés en 5 groupes :
- 8 bits (4 bits pour la version et 4 bits pour les variantes) : ces bits spécifient la version (0100) et le variant (10xxxxxx).
- 64 bits : ces bits sont générés de manière aléatoire.
- 4 bits : ces bits sont utilisés pour définir les drapeaux de contrôle et d'autres informations, bien qu'ils soient toujours fixés à des valeurs spécifiques pour l'UUID v4.
- 2 groupes de 48 bits chacun : ces bits sont également générés de manière aléatoire et sont souvent représentés sous forme de deux blocs de 12 caractères hexadécimaux séparés par des tirets.
Pour que mon explication soit la plus claire possible, voici un exmple détaillé :
UUID v4 : f47ac10b-58cc-4372-a567-0e02b2c3d479
Version: (f4)
La première partie de l'UUID, spécifie la version de l'UUID. Pour l'UUID v4, la version est toujours 4.
Variant: (7)
La partie suivante, (7), spécifie le variant de l'UUID. Pour l'UUID v4, le variant est toujours 7 ou 8.
Aléatoire :
Les caractères suivants de l'UUID, ac10b58cc4372a5670e02b2c3d479, représentent les 122 bits générés de manière aléatoire.
Avantages de l'utilisation d'un UUID
Unicité
L'avantage principal d'un UUID est qu'il est unique sur l'entièreté d'un système le rendant donc parfait pour identifier des données (ou des utilisateurs). Il faut savoir que si vous êtes autants inqués que moi, à l'idée d'avoir un doublon dans vos UUIDs, sachez que la probabilité qu'il y ait deux uuids identifiques dans un groupe de 3.26*10¹⁶ (soit 32'600'000'000'000'000) est de seulement 0.01%. Si on génère 1 UUID toutes les milisecondes, arriver à ce tel échantillon prendrait seulement 20s 33mins 19heures 79jours 1'033'739ans.
Aucune dépendance & Rapidité de calcul
Les UUIDs ne sont, qu'a leur coeur, une représentation hexadécimale de 6bits et d'une valeur aléatoire de 122bits. Ce standard rendu public par la RFC4122 est implémenté dans beaucoup de languages et n'a pas besoin de beaoup de puissance de calcul, le rendant facile a générer sur tous types de plateformes.
Systèmes de grande taille
Les UUIDs sont parfaits si vous avez un système d'information très important sur plusieurs serveurs. Immaginons que nous avons 5 serveurs et une base de donnée utilisée par les 5 serveurs. Si on utilise un auto_increment, il se peut que deux serveurs essaient d'inserer une ligner avec la même clef primaire. Avec les UUIDs, l'opération est simple, juste besoin d'en générer un et d'inserer.
Désavantages de l'utilisation d'un UUID
Taille
Comme établi précédament, chaque UUID fait 128bits, ce qui est sinificativement plus gros que juste un entier qu'on incrémente à chaque nouvelle itération dans une base de donnée. Mais UUID peut aussi peser beaucoup plus que 128bits. Si un UUID est stocké d'une mauvaise manière, disons sous forme d'un VARCHAR(36) dans une base de donnée MySQL, chaque caractère (si stocké en UTF-8) prendrait 4octets soit 32bits et notre UUID prendrait 1152bits
Performance
Les UUIDs sont des identifiant très longs (beaucoup plus long qu'un simple entier) et peuvent ralentir certains gestionnaires de données (par exemple MySQL). Dans le benchmark de Saeed Anabtawi sur linkedin on peut voir qu'un UUID mal stocké (utf-8) peut considérablement augmenter le temps de traitement de quelques itérations (96.29ms pour 100 UUIDs mal stockés contre 0.11ms pour 10'000 UUIDs bien stockés et 0.07ms pour 10'000 itération avec un identifiant sous forme d'entier)
Debug
Lire un UUID peut être plus compliqué là ou un identifiant sous forme d'entier peut être plus pratique. Prennons l'exemple de logs, il est facile de voir que l'évènement 29 est arrivé avant l'évènement 60. Essayez de faire aussi simple avec des UUIDs.
Conclusion
En conclusion, les UUIDs sont des identifiants parfaits si vous savez les stocker et les utiliser convenablement avec une garantie presque parfaite de jamais génrer de doublon. Si votre application ou projet à besoin d'une réponse hyper rapide, si le stockage est quelque chose de rare ou que vous ne pouvez pas envisager un check supplémentaire ou le risque d'avoir un doublon alors laissez tombez les UUIDs et partez avec une approche plus basique avec chaque serveur génère des identifiants dans un parc précis.
Sources
Cet article s'est appuyé sur les sources suivantes : https://www.percona.com/blog/to-uuid-or-not-to-uuid/ https://stackoverflow.com/questions/2365132/uuid-performance-in-mysql https://blog.boot.dev/clean-code/what-are-uuids-and-should-you-use-them/ https://towardsdatascience.com/are-uuids-really-unique-57eb80fc2a87 https://dev.to/frederik_vl/why-you-should-never-use-an-uuid-as-the-primary-key-in-sql-databases-147b https://www.linkedin.com/pulse/pros-cons-using-uuids-unique-identification-saeed-anabtawi/ https://datatracker.ietf.org/doc/html/rfc4122