Realmente no veo el punto de UUID . Sé que la probabilidad de una colisión es efectivamente nula , pero efectivamente nula ni siquiera es casi imposible.
¿Alguien puede dar un ejemplo en el que no tenga más remedio que usar UUID? De todos los usos que he visto, puedo ver un diseño alternativo sin UUID. Claro que el diseño puede ser un poco más complicado, pero al menos no tiene una probabilidad de falla distinta de cero.
UUID huele a variables globales para mí. Hay muchas formas en que las variables globales hacen que el diseño sea más simple, pero es solo un diseño vago.
architecture
uuid
Pirolista
fuente
fuente
Respuestas:
Escribí el generador / analizador UUID para Ruby, por lo que me considero razonablemente bien informado sobre el tema. Hay cuatro versiones principales de UUID:
Los UUID de la versión 4 son esencialmente solo 16 bytes de aleatoriedad extraídos de un generador de números aleatorios criptográficamente seguro, con algunos cambios de bits para identificar la versión y variante del UUID. Es extremadamente improbable que estos choquen, pero podría suceder si se usa un PRNG o si resulta que tienes mucha, mucha, mucha, mucha, mucha mala suerte.
Los UUID de la Versión 5 y la Versión 3 usan las funciones hash SHA1 y MD5 respectivamente, para combinar un espacio de nombres con una pieza de datos ya únicos para generar un UUID. Esto, por ejemplo, le permitirá producir un UUID desde una URL. Las colisiones aquí solo son posibles si la función hash subyacente también tiene una colisión.
Los UUID de la versión 1 son los más comunes. Utilizan la dirección MAC de la tarjeta de red (que, a menos que sea falsa, debe ser única), más una marca de tiempo, más el giro de bits habitual para generar el UUID. En el caso de una máquina que no tiene una dirección MAC, los bytes de 6 nodos se generan con un generador de números aleatorios criptográficamente seguro. Si se generan dos UUID en secuencia lo suficientemente rápido como para que la marca de tiempo coincida con el UUID anterior, la marca de tiempo se incrementa en 1. Las colisiones no deberían ocurrir a menos que ocurra una de las siguientes situaciones: la dirección MAC es falsa; Una máquina que ejecuta dos aplicaciones generadoras de UUID diferentes produce UUID en el mismo momento; Dos máquinas sin una tarjeta de red o sin acceso de nivel de usuario a la dirección MAC reciben la misma secuencia de nodo aleatorio y generan UUID en el mismo momento exacto;
Siendo realistas, ninguno de estos eventos ocurre por accidente dentro del espacio de identificación de una sola aplicación. A menos que acepte identificaciones en, por ejemplo, una escala de Internet, o con un entorno no confiable en el que las personas malintencionadas puedan hacer algo malo en el caso de una colisión de identificaciones, simplemente no es algo de lo que deba preocuparse. Es fundamental comprender que si genera la misma versión 4 UUID que yo, en la mayoría de los casos, no importa. He generado la ID en un espacio de ID completamente diferente al tuyo. Mi aplicación nunca sabrá sobre la colisión, por lo que la colisión no importa. Francamente, en un solo espacio de aplicación sin actores maliciosos, la extinción de toda la vida en la tierra ocurrirá mucho antes de que tenga una colisión, incluso en un UUID de versión 4, incluso si usted '
Además, 2 ^ 64 * 16 son 256 exabytes. Como en, necesitaría almacenar 256 exabytes de ID antes de tener una probabilidad del 50% de una colisión de ID en un solo espacio de aplicación.
fuente
uuid.raw
te dará la cadena de bytes. Elhash
método no es útil para ti. Se utiliza para tablas hash y operaciones de comparación internamente dentro de Ruby. Todos los métodos para convertir ay desde varias representaciones de UUID se definen como métodos de clase y deben tener como prefijo"parse"
.Lo que le compran los UUID que es muy difícil de hacer de otra manera es obtener un identificador único sin tener que consultar o coordinar con una autoridad central . El problema general de poder obtener tal cosa sin algún tipo de infraestructura administrada es el problema que resuelven los UUID.
He leído que, según la paradoja del cumpleaños, la posibilidad de que se produzca una colisión UUID es del 50% una vez que se han generado 2 ^ 64 UUID. Ahora 2 ^ 64 es un número bastante grande, pero un 50% de posibilidades de colisión parece demasiado arriesgado (por ejemplo, cuántos UUID deben existir antes de que haya un 5% de posibilidades de colisión, incluso eso parece una probabilidad demasiado grande) .
El problema con ese análisis es doble:
Los UUID no son completamente al azar: hay componentes principales del UUID que se basan en el tiempo y / o la ubicación. Por lo tanto, para tener una posibilidad real de colisión, los UUID en colisión deben generarse al mismo tiempo desde diferentes generadores de UUID. Yo diría que si bien existe una posibilidad razonable de que se puedan generar varios UUID al mismo tiempo, hay suficiente cantidad de datos (incluida información de ubicación o bits aleatorios) para hacer casi imposible la posibilidad de una colisión entre este conjunto muy pequeño de UUID .
estrictamente hablando, los UUID solo necesitan ser únicos entre el conjunto de otros UUID con los que podrían compararse. Si está generando un UUID para usarlo como clave de base de datos, no importa si en otro lugar en un universo alternativo malvado se está utilizando el mismo UUID para identificar una interfaz COM. Al igual que no causará confusión si hay alguien (o algo) llamado "Michael Burr" en Alpha-Centauri.
fuente
Todo tiene una probabilidad de fracaso distinta de cero. Me concentraría en problemas mucho más probables (es decir, casi cualquier cosa que se te ocurra) que la colisión de UUID
fuente
Un énfasis en "razonablemente" o, como lo dice, "efectivamente": lo suficientemente bueno es cómo funciona el mundo real. La cantidad de trabajo computacional involucrado en cubrir esa brecha entre "prácticamente único" y "verdaderamente único" es enorme. La unicidad es una curva con rendimientos decrecientes. En algún punto de esa curva, hay una línea entre donde "lo suficientemente único" todavía es asequible, y luego nos curvamos MUY abruptamente. El costo de agregar más singularidad se vuelve bastante grande. La unicidad infinita tiene un costo infinito.
UUID / GUID es, en términos relativos, una manera computacionalmente rápida y fácil de generar una ID que se puede suponer razonablemente que es universalmente única. Esto es muy importante en muchos sistemas que necesitan integrar datos de sistemas previamente desconectados. Por ejemplo: si tiene un sistema de gestión de contenido que se ejecuta en dos plataformas diferentes, pero en algún momento necesita importar el contenido de un sistema a otro. No desea que las ID cambien, por lo que sus referencias entre los datos del sistema A permanecen intactas, pero no desea ninguna colisión con los datos creados en el sistema B. Un UUID resuelve esto.
fuente
Nunca es absolutamente necesario crear un UUID. Sin embargo, es conveniente tener un estándar donde los usuarios sin conexión puedan generar una clave para algo con una probabilidad muy baja de colisión.
Esto puede ayudar en la resolución de replicación de la base de datos, etc.
Sería fácil para los usuarios en línea generar claves únicas para algo sin la sobrecarga o la posibilidad de colisión, pero eso no es para lo que son los UUID.
De todos modos, una palabra sobre la probabilidad de colisión, tomada de Wikipedia:
fuente
Un ejemplo clásico es cuando está replicando entre dos bases de datos.
DB (A) inserta un registro con ID 10 y al mismo tiempo DB (B) crea un registro con ID 10. Esto es una colisión.
Con UUID esto no sucederá ya que no coincidirán. (casi seguro)
fuente
También hay una probabilidad distinta de cero de que cada partícula en su cuerpo haga un túnel simultáneamente a través de la silla en la que está sentado y de repente se encontrará sentado en el piso.
¿Te preocupa eso?
fuente
Tengo un esquema para evitar UUID. Configure un servidor en algún lugar y téngalo de modo que cada vez que una pieza de software quiera un identificador universalmente único, se comunique con ese servidor y lo entregue. ¡Sencillo!
Excepto que hay algunos problemas prácticos reales con esto, incluso si ignoramos la malicia absoluta. En particular, ese servidor puede fallar o no ser accesible desde una parte de Internet. Lidiar con la falla del servidor requiere replicación, y eso es muy difícil de corregir (consulte la literatura sobre el algoritmo de Paxos para saber por qué la creación de consenso es incómoda) y también es bastante lenta. Además, si no se puede acceder a todos los servidores desde una parte particular de la red, ninguno de los clientes conectados a esa subred podrá hacer nada porque todos estarán esperando nuevas identificaciones.
Entonces ... use un algoritmo probabilístico simple para generarlos que es poco probable que falle durante la vida útil de la Tierra, o (financie y) construya una infraestructura importante que será un PITA de despliegue y tenga fallas frecuentes. Sé cuál elegiría.
fuente
No entiendo todo sobre la probabilidad de colisión. No me importa la colisión. Aunque me importa el rendimiento.
https://dba.stackexchange.com/a/119129/33649
fuente
Si solo mira las alternativas, por ejemplo, para una aplicación de base de datos simple, para tener que consultar la base de datos cada vez antes de crear un nuevo objeto, pronto descubrirá que usar UUID puede reducir efectivamente la complejidad de su sistema. De acuerdo: si usa las teclas int, son de 32 bits, que se almacenarán en una cuarta parte del UUID de 128 bits. Concedido: los algoritmos de generación de UUID requieren más potencia computacional que simplemente incrementar un número. ¿Pero a quién le importa? La sobrecarga de administrar una "autoridad" para asignar números que de otro modo serían únicos supera fácilmente eso por órdenes de magnitud, dependiendo de su espacio de identificación de unicidad previsto.
fuente
En UUID == diseño perezoso
No estoy de acuerdo, se trata de elegir tus peleas. Si un UUID duplicado es estadísticamente imposible y se prueban las matemáticas, ¿por qué preocuparse? Pasar tiempo diseñando alrededor de su pequeño sistema generador de N UUID no es práctico, siempre hay una docena de otras formas en que puede mejorar su sistema.
fuente
En mi último trabajo, recibíamos objetos de terceros que estaban identificados de forma exclusiva con UUID. Puse una tabla de búsqueda de entero largo UUID-> y utilicé entero largo como mis claves principales porque era mucho más rápido de esa manera.
fuente
Usando el algoritmo de la versión 1 parece que es imposible una colisión bajo la restricción de que se generan menos de 10 UUID por milisegundo a partir de la misma dirección MAC
Alguien me corrige si malinterpreto cómo funciona
fuente
Para aquellos que dicen que los UUID son un mal diseño porque podrían (con una probabilidad ridículamente pequeña) colisionar, mientras que sus claves generadas por DB no ... saben la posibilidad de que un error humano provoque una colisión en sus claves generadas por DB debido a algunos -la necesidad prevista es MUCHO MUCHO MUCHO mayor que la posibilidad de colisión UUID4. Nos saber que si se vuelve a crear la base de datos se iniciará en los identificadores de 1 de nuevo, y cómo muchos de nosotros hemos tenido que volver a crear una mesa cuando estábamos seguros de que nunca necesitaríamos? Pondría mi dinero en la seguridad de UUID cuando las cosas comienzan a salir mal con incógnitas desconocidas cualquier día.
fuente
Además de los casos en los que tiene que usar la API de otra persona que exige un UUID, por supuesto, siempre hay otra solución. ¿Pero esas alternativas resolverán todos los problemas que hacen los UUID? ¿Terminará agregando más capas de hacks, cada una para resolver un problema diferente, cuando podría haber resuelto todos a la vez?
Sí, teóricamente es posible que los UUID choquen. Como otros han señalado, es ridículamente improbable hasta el punto de que simplemente no valga la pena considerarlo. Nunca ha sucedido hasta la fecha y probablemente nunca lo hará. Olvídalo.
La forma más "obvia" de evitar colisiones es dejar que un solo servidor genere ID únicos en cada inserción, lo que obviamente crea serios problemas de rendimiento y no resuelve el problema de generación fuera de línea. Ups
La otra solución "obvia" es una autoridad central que entrega bloques de números únicos por adelantado, que es esencialmente lo que hace UUID V1 al usar la dirección MAC de la máquina generadora (a través de IEEE OUI). Pero las direcciones MAC duplicadas suceden porque eventualmente todas las autoridades centrales se equivocan, por lo que en la práctica esto es mucho más probable que una colisión UUID V4. Ups
El mejor argumento contra el uso de UUID es que son "demasiado grandes", pero un esquema (significativamente) más pequeño inevitablemente no resolverá los problemas más interesantes; El tamaño de los UUID es un efecto secundario inherente de su utilidad para resolver esos mismos problemas.
Es posible que su problema no sea lo suficientemente grande como para necesitar lo que ofrecen los UUID y, en ese caso, no dude en usar otra cosa. Pero si su problema crece inesperadamente (y la mayoría lo hace), terminará cambiando más tarde, y se pateará por no usarlos en primer lugar. ¿Por qué diseñar para el fracaso cuando es tan fácil diseñar para el éxito?
fuente
Los UUID incorporan todas las malas prácticas de codificación asociadas con las variables globales, solo que peor, ya que son variables superglobales que pueden distribuirse en diferentes piezas del kit.
Recientemente tuve un problema con el reemplazo de una impresora con un modelo de reemplazo exacto, y descubrí que ninguno de los software del cliente funcionaría.
fuente