MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Utilisation d'UUID au lieu d'ObjectID dans MongoDB

L'utilisation d'UUID dans Mongo est certainement possible et raisonnablement bien prise en charge. Par exemple, les documents Mongo répertorient les UUID comme l'une des options courantes pour le _id champ.

Considérations

  • Performances – Comme d'autres réponses le mentionnent, les benchmarks montrent que les UUID entraînent une baisse des performances pour les insertions. Dans le pire des cas mesurés (passant de 10 millions à 20 millions de documents dans une collection), ils sont environ 2 à 3 fois plus lents - la différence entre l'insertion de 2 000 (UUID) et 7 500 (ObjectID) documents par seconde. C'est une grande différence mais sa signification dépend entièrement de votre cas d'utilisation. Allez-vous insérer par lots des millions de documents à la fois ? Pour la plupart des applications que j'ai créées, le cas courant consiste à insérer des documents individuels. Les mêmes repères montrent que, pour ce modèle d'utilisation, la différence est beaucoup plus petit (6 250 -vs- 7 500; ~20 %). Pas insignifiant... mais pas renversant non plus.
  • Portabilité – De nombreuses autres plates-formes de base de données ont une bonne prise en charge des UUID, ce qui améliore la portabilité. Alternativement, puisque les UUID sont plus grands (plus de bits), il est possible de reconditionner un ObjectID dans la "forme" d'un UUID. Cette approche n'est pas aussi agréable que la portabilité directe, mais elle vous permet de "mapper" entre les ObjectID et les UUID existants.
  • Décentralisation – L'un des principaux arguments de vente des UUID est qu'ils sont universellement uniques. Cela rend pratique de les générer n'importe où, de manière décentralisée (contrairement, par exemple, à une valeur auto-incrémentée, qui nécessite une source de vérité centralisée pour déterminer la valeur "suivante"). Bien entendu, les identifiants d'objet Mongo présentent également cet avantage. La différence est que les UUID sont basés sur une norme vieille de plus de 15 ans et pris en charge sur (presque ?) Toutes les plates-formes, langues, etc. Cela les rend très utiles si vous avez besoin de créer des entités (ou plus précisément, des ensembles de liés entités) dans des systèmes disjoints, sans interagir avec la base de données. Vous pouvez créer un jeu de données avec des identifiants et des clés étrangères en place, puis écrire le graphique entier dans la base de données à un moment donné dans le futur sans conflit. Bien que cela soit également possible avec les ObjectID Mongo, trouver le code pour les générer/travailler avec le format sera souvent plus difficile.

Corrections

Contrairement à certaines des autres réponses :

  • Les UUID ont une prise en charge native de Mongo – Vous pouvez utiliser le UUID() fonction dans le Mongo Shell exactement de la même manière que vous utiliseriez ObjectID(); pour convertir une chaîne UUID en objet BSON équivalent.
  • Les UUID ne sont pas particulièrement grands – Lorsqu'il est encodé à l'aide du sous-type binaire 0x04 ils sont de 128 bits, contre 96 bits pour les ObjectID. (Si elles sont encodées sous forme de chaînes, elles seront être assez inutile, prenant environ 288 bits.)
  • Les UUID peuvent inclure un horodatage – Plus précisément, UUIDv1 encode un horodatage avec 60 bits de précision, contre 32 bits dans les ObjectID. C'est plus de 6 ordres de grandeur de précision, donc des nanosecondes au lieu de secondes. Cela peut en fait être un moyen décent de stocker les horodatages de création avec plus de précision que la prise en charge des objets de date Mongo/JS, cependant...
    • La construction dans UUID() la fonction ne génère que des UUID v4 (aléatoires), donc, pour tirer parti de cela, vous devez vous appuyer sur votre application ou sur le pilote Mongo pour la création d'ID.
    • Contrairement aux ObjectID, en raison de la façon dont les UUID sont fragmentés, l'horodatage ne vous donne pas un ordre naturel. Cela peut être bon ou mauvais selon votre cas d'utilisation. (De nouvelles normes peuvent changer cela ; voir la mise à jour 2021 ci-dessous.)
    • Inclure des horodatages dans vos identifiants est parfois une mauvaise idée. Vous finissez par divulguer l'heure de création des documents partout où un identifiant est exposé. (Bien sûr, les ObjectID encodent également un horodatage, c'est donc en partie vrai pour eux aussi.)
    • Si vous faites cela avec des UUID v1 (conformes aux spécifications), vous encodez également une partie de l'adresse MAC des serveurs, qui peut potentiellement être utilisé pour identifier la machine. Ce n'est probablement pas un problème pour la plupart des systèmes, mais ce n'est pas non plus idéal. (De nouvelles normes peuvent changer cela ; voir la mise à jour 2021 ci-dessous.)

Conclusion

Si vous pensez à votre base de données Mongo de manière isolée, les ObjectID sont le choix évident. Ils fonctionnent bien hors de la boîte et sont un défaut parfaitement capable. Utiliser des UUID à la place fait ajouter un peu de friction, à la fois lorsque vous travaillez avec les valeurs (nécessité de convertir en types binaires, etc.) et en termes de performances. Que ce léger inconvénient vaille la peine d'avoir un format d'identification standardisé dépend vraiment de l'importance que vous accordez à la portabilité et de vos choix architecturaux.

Allez-vous synchroniser les données entre différentes plates-formes de bases de données ? Allez-vous migrer vos données vers une autre plate-forme à l'avenir ? Avez-vous besoin de générer des identifiants dehors la base de données, dans d'autres systèmes ou dans le navigateur ? Si ce n'est pas maintenant à un moment donné dans le futur ? Les UUID pourraient valoir la peine.

Mise à jour d'août 2021

L'IEFT a récemment publié un projet de mise à jour de la spécification UUID qui introduirait de nouvelles versions du format.

Plus précisément, UUIDv6 et UUIDv7 sont basés sur UUIDv1 mais inversent les morceaux d'horodatage afin que les bits soient disposés du plus significatif au moins significatif. Cela donne aux valeurs résultantes un ordre naturel qui (plus ou moins) reflète l'ordre dans lequel elles ont été créées. Les nouvelles versions excluent également les données dérivées de l'adresse MAC des serveurs, répondant à une critique de longue date des UUID v1.

Il faudra du temps pour que ces changements se répercutent sur les implémentations, mais (à mon humble avis), ils modernisent et améliorent considérablement le format.