Je comprends les différences entre les deux de la documentation.
uuid1()
:
Générer un UUID à partir d'un ID d'hôte, d'un numéro de séquence et de l'heure actuelle
uuid4()
:
Générer un UUID aléatoire.
uuid1
Utilise donc les informations machine / séquence / heure pour générer un UUID. Quels sont les avantages et les inconvénients de chacun?
Je sais que cela uuid1()
peut avoir des problèmes de confidentialité, car il est basé sur des informations sur la machine. Je me demande s'il y a plus de subtilité dans le choix de l'un ou de l'autre. J'utilise juste en uuid4()
ce moment, car c'est un UUID complètement aléatoire. Mais je me demande si je devrais utiliser uuid1
pour réduire le risque de collisions.
Fondamentalement, je suis à la recherche de conseils sur les meilleures pratiques d'utilisation de l'un par rapport à l'autre. Merci!
Réponses:
uuid1()
est garanti de ne pas produire de collisions (en supposant que vous n'en créez pas trop en même temps). Je ne l'utiliserais pas s'il est important qu'il n'y ait pas de connexion entreuuid
l'ordinateur et l'ordinateur, car l'adresse mac est utilisée pour la rendre unique sur tous les ordinateurs.Vous pouvez créer des doublons en créant plus de 2 14 uuid1 en moins de 100ns, mais ce n'est pas un problème pour la plupart des cas d'utilisation.
uuid4()
génère, comme vous l'avez dit, un UUID aléatoire. Le risque de collision est vraiment, vraiment, vraiment très faible. Assez petit, que vous ne devriez pas vous en soucier. Le problème est qu'un mauvais générateur de nombres aléatoires le rend plus susceptible d'avoir des collisions.Cette excellente réponse de Bob Aman le résume bien. (Je recommande de lire toute la réponse.)
la source
uuid1
ne produira pas nécessairement des UUID uniques si vous en produisez plusieurs par seconde sur le même nœud. Exemple:[uuid.uuid1() for i in range(2)]
. À moins bien sûr qu'il se passe quelque chose d'étrange qui me manque.uuid1
a un numéro de séquence (4ème élément dans votre exemple), donc à moins que vous n'utilisiez tous les bits du compteur, vous n'avez pas de collision.Un exemple , lorsque vous pouvez envisager
uuid1()
plutôt queuuid4()
est quand UUID sont produits sur des machines séparées , par exemple lorsque plusieurs transactions en ligne sont processus sur plusieurs machines à des fins d' échelle.Dans une telle situation, les risques d'avoir des collisions en raison de mauvais choix dans la façon dont les générateurs de nombres pseudo-aléatoires sont initialisés, par exemple, et aussi le nombre potentiellement plus élevé d'UUID produits rendent plus probable la possibilité de créer des ID en double.
Un autre intérêt de
uuid1()
, dans ce cas, est que la machine sur laquelle chaque GUID a été initialement produit est implicitement enregistrée (dans la partie "nœud" de l'UUID). Ceci et les informations de temps peuvent aider, ne serait-ce qu'avec le débogage.la source
Mon équipe vient de rencontrer des problèmes en utilisant UUID1 pour un script de mise à niveau de base de données où nous avons généré ~ 120k UUID en quelques minutes. La collision UUID a entraîné la violation d'une contrainte de clé primaire.
Nous avons mis à niveau des centaines de serveurs, mais sur nos instances Amazon EC2, nous avons rencontré ce problème à plusieurs reprises. Je soupçonne une mauvaise résolution d'horloge et le passage à UUID4 l'a résolu pour nous.
la source
Une chose à noter lors de l'utilisation
uuid1
, si vous utilisez l'appel par défaut (sans donner declock_seq
paramètre), vous avez une chance de tomber dans des collisions: vous n'avez que 14 bits d'aléatoire (générer 18 entrées en 100ns vous donne environ 1% de chance de collision voir paradoxe anniversaire / attaque). Le problème ne se produira jamais dans la plupart des cas d'utilisation, mais sur une machine virtuelle avec une mauvaise résolution d'horloge, il vous mordra.la source
clock_seq
....Peut-être que quelque chose qui n'a pas été mentionné est celui de la localité.
Une adresse MAC ou un ordre temporel (UUID1) peut offrir des performances de base de données accrues, car il est moins difficile de trier les nombres plus étroitement que ceux distribués de manière aléatoire (UUID4) (voir ici ).
Un deuxième problème connexe est que l'utilisation de UUID1 peut être utile dans le débogage, même si les données d'origine sont perdues ou ne sont pas explicitement stockées (cela est évidemment en conflit avec le problème de confidentialité mentionné par l'OP).
la source
En plus de la réponse acceptée, il existe une troisième option qui peut être utile dans certains cas:
v1 avec MAC aléatoire ("v1mc")
Vous pouvez créer un hybride entre v1 et v4 en générant délibérément des UUID v1 avec une adresse MAC de diffusion aléatoire (cela est autorisé par la spécification v1). L'UUID v1 résultant dépend du temps (comme la v1 normale), mais il manque toutes les informations spécifiques à l'hôte (comme la v4). Il est également beaucoup plus proche de la v4 dans sa résistance aux collisions: v1mc = 60 bits de temps + 61 bits aléatoires = 121 bits uniques; v4 = 122 bits aléatoires.
Le premier endroit où j'ai rencontré cela était la fonction uuid_generate_v1mc () de Postgres . J'ai depuis utilisé l'équivalent python suivant:
(Remarque: j'ai une version plus longue + plus rapide qui crée directement l'objet UUID; peut publier si quelqu'un le veut)
En cas de grands volumes d'appels / seconde, cela a le potentiel d'épuiser le caractère aléatoire du système. Vous pouvez utiliser le
random
module stdlib à la place (il sera probablement aussi plus rapide). Mais ATTENTION: il ne faut que quelques centaines d'UUID avant qu'un attaquant puisse déterminer l'état RNG, et donc prédire partiellement les futurs UUID.la source