UUID vs identifiants auto-incrémentés

Les identifiants auto-incrémentés ne sont pas toujours la bonne solution. Cependant c'est celle qu'on utilise la plupart du temps. Les UUID peuvent pourtant parfois nous faciliter la vie. Alors quels sont les avantages et inconvénients de l'Universal Unique Identifier (UUID) ? Et pourquoi les utiliser dans votre actuel ou prochain projet ?

Généré sans base de données

Aucune vérification dans la base de données avant insertion. Vous pouvez générer un UUID sans interroger la base de données.

Compatibles avec les frameworks et ORM

Les repositories de Spring gèrent très bien les UUID avec la généricité.

Vous pouvez donc marquer :

public interface UserRepository extends Repository<User, UUID> { … }

Unique (en pratique)

En pratique les UUID sont uniques. La probabilité de générer un UUID non unique est minuscule. Pour avoir une chance sur deux de générer un doublon, il faudrait générer plus de 2 quintillions d'UUID...

Par contre, les ID auto-incrémentés des bases de données ne sont pas universels.

Les ID auto-incrémentés ne peuvent pas être utilisés dans une autre base de données puisque les ID dépendent de celle-ci.

Les UUID prennent plus de place

Les UUID sont codés sur 128 bits. Donc en effet, ils prennent plus de place.

Vous pouvez les stocker en binaire ou les indexer pour accélérer les requêtes.

Les UUID ne sont pas user-friendly

Imaginons les URLs suivantes :

https://bibliotheque.fr/livres/5ed22070-da8f-4968-a016-398456a02f2a

https://bibliotheque.fr/livres/52

Horrible n'est-ce pas ?

Oui, les UUID sont trop longs...

Non ! Le problème n'est pas là... Le problème c'est que l'on vient d'exposer un UUID ou un ID que l'utilisateur n'est pas censé voir !

Pourquoi l'utilisateur n'est pas censé voir un ID ou un UUID ?

Dans certains cas, l'identifiant est créé par le domaine. Dans ce cas-là, identifiant doit être montré à l'utilisateur. L'ISBN par exemple pour des livres (qu'il ne faut pas utiliser comme identifiant dans une base de données d'ailleurs...)

Dans la plupart des cas l'identifiant n'est pas créé par le domaine métier, il a été créé pour la base de données pour garantir l'unicité d'une ligne.

D'ailleurs, rien ne vous empêche de créer un autre identifiant dans une table ou entité. Par exemple, si certains livres n'ont pas d'ISBN, un autre identifiant serait le bienvenu pour garantir l'unicité des livres dans votre base de données...

De plus, dans le cas d'identifiants incrémentés, si un livre à l'ID 52 l'utilisateur devine qu'il y a peut-être un livre 51 ou 50 ?

Ça ne pose pas trop de problèmes si ce sont des livres... mais pour des utilisateurs ? Savoir qui a été inscrit avant quelqu'un d'autre...

Ça donne beaucoup trop d'informations au client.

Il existe les sequences pour personnaliser les ID avec pseudo_encrypt sur nextval qui permettent d'éviter ce problème d'ordre.

Ce serait tellement mieux d'offrir à ses clients une URL suivante :

https://bibliotheque.fr/livres/tolkien-le-hobbit

Le lien parle de lui-même... Je sais sur quoi je clique. Et ça améliore le SEO.

Vous pouvez rendre n'importe quelle ligne unique avec les contraintes ! Donc pour une table livre vous pouvez utiliser une propriété nom_unique ou url_name par exemple et qui serait unique.

Les UUID ne permettent pas d'obtenir l'ordre d'insertion.

Si le temps importe autant pourquoi ne pas ajouter une ligne avec la date, l'heure, les minutes et les secondes (datetime) de l'insertion ? ou bien une ligne avec une valeur auto incrémenté nommé ordre_insertion.

Si ces choses font partie de votre domaine métier, elles doivent figurer dans la base de données. Les attributs auto-incrémenté ne sont pas limités aux clés primaires.

Un identifiant est fait pour identifier une entité... pas pour connaitre l'ordre d'insertion.

Conclusion

Les UUID sont une très bonnes alternatives aux identifiants auto-incrémentés et une bonne pratiques de développement. Vous universalisez vos identifiants ce qui est une bonne chose. Les UUID peuvent être utilisée dans les applications de grande envergure.

Si vous n'utilisez pas UUID pour des raisons de performance (UUID est trop lourd), pensez à utiliser des séquences personnalisés et aléatoires (pseudo_encrypt).

Dans tous les cas, il ne faut pas afficher un identifiant qui n'a pas d'utilité (voire même de sens...) pour l'utilisateur.

Commentaires