type tutorial query queries importar example data all mongodb

tutorial - Uso de UUID en lugar de ObjectID en MongoDB



query document mongodb (4)

Estamos migrando una base de datos de MySQL a MongoDB por razones de rendimiento y considerando qué utilizar para las ID de los documentos de MongoDB. Estamos debatiendo entre usar ObjectIDs, que es el valor predeterminado de MongoDB, o usar UUIDs (que es lo que hemos estado usando hasta ahora en MySQL). Hasta ahora, los argumentos que tenemos para apoyar cualquiera de estas opciones son los siguientes:

ObjectIDs: los ObjectID son el valor predeterminado de MongoDB y asumo (aunque no estoy seguro) que esto es por una razón, lo que significa que espero que MongoDB pueda manejarlos más eficientemente que los UUID o tenga otra razón para preferirlos. También encontré esta respuesta de stackoverflow que menciona que el uso de ObjectID hace que la indexación sea más eficiente, sin embargo, sería bueno tener algunas métricas sobre qué tan "más eficiente" es este.

UUID: nuestro argumento básico a favor del uso de UUID (y es muy importante) es que están respaldados, de una forma u otra, por prácticamente cualquier base de datos. Esto significa que si de algún modo decidimos cambiar de MongoDB a otra cosa por cualquier motivo y ya tenemos una API que recupera documentos de la base de datos en función de sus ID, nada cambia para los clientes de esta API ya que las ID pueden continuar. para ser exactamente el mismo. Si tuviéramos que utilizar ObjectIDs, no estoy realmente seguro de cómo podríamos migrarlos a otra base de datos.

¿Alguien tiene alguna idea sobre si una de estas opciones puede ser mejor que la otra y por qué? ¿Alguna vez ha utilizado UUID en MongoDB en lugar de ObjectID y, en caso afirmativo, cuáles fueron las ventajas / problemas que encontró?


Considere la cantidad de datos que almacenaría en cada caso.

Un ID de ObjectID MongoDB tiene un tamaño de 12 bytes, se empaqueta para el almacenamiento y sus partes se organizan para el rendimiento (es decir, la marca de tiempo se almacena primero, lo cual es un criterio de ordenamiento lógico).

A la inversa, un UUID estándar es de 36 bytes, contiene guiones y normalmente se almacena como una cadena. Además, incluso si elimina los caracteres no numéricos y tiene la intención de almacenarlos numéricamente, todavía debe contentarse con su parte "indexada" (la parte de un UUID v1 que está basada en la marca de tiempo) está en el medio del UUID, y no Se presta bien a la clasificación. Hay studies realizados que permiten el almacenamiento de UUID, e incluso escribí una biblioteca Node.js para ayudar en su gestión.

Si tiene la intención de usar un UUID, considere reorganizarlo para una indexación y clasificación óptimas; de lo contrario es probable que golpee un muro de rendimiento.


Creo que esta es una gran idea y también Mongo; listan los UUID como una de las opciones comunes para el campo _id .

Consideraciones:

  • Rendimiento : como mencionan otras respuestas, los benchmarks muestran que los UUID provocan una caída en el rendimiento de las inserciones. En el peor de los casos (que van de 10M a 20M documentos en una colección) tienen aproximadamente ~ 2-3x más lento, la diferencia entre insertar 2,000 (UUID) y 7,500 (ObjectID) documentos por segundo. Esta es una gran diferencia, pero su importancia depende totalmente de su caso de uso. ¿Estarás insertando por lotes millones de documentos a la vez? Para la mayoría de las aplicaciones que he creado, el caso común es insertar documentos individuales. En esa prueba, la diferencia es mucho menor (6,250-vs-7,500; ~ 20%). El tipo de ID simplemente no es el factor limitante.
  • Portabilidad : otras bases de datos ciertamente tienden a tener un buen soporte UUID por lo que la portabilidad se mejoraría. Alternativamente, como los UUID son más grandes (más bits), es posible volver a empaquetar un ObjectID en la "forma" de un UUID . Este enfoque no es tan bueno como la portabilidad directa, pero le da un camino a seguir.

En contra de algunas de las otras respuestas:

  • Los UUID tienen soporte nativo : puedes usar la función UUID() en el Mongo Shell exactamente de la misma manera que ObjectID() ; para convertir una cadena en un objeto BSON equivalente.
  • Los UUID no son especialmente grandes : son de 128 bits en comparación con los ObjectID que tienen 96 bits. (Deben codificarse utilizando el subtipo binario 0x04 ).
  • Los UUID pueden incluir una marca de tiempo . Específicamente, UUIDv1 codifica una marca de tiempo con 60 bits de precisión, en comparación con los 32 bits de los ObjectID. Esto es más de 6 órdenes de magnitud más precisión, por lo que nano-segundos en lugar de segundos. En realidad, puede ser una forma decente de almacenar las marcas de tiempo de creación con más precisión que la que admiten los objetos Mongo / JS Date, sin embargo ...
    • La función de compilación en UUID() solo genera UUID() v4 (aleatorios), por lo tanto, para aprovechar esto, debería apoyarse en su aplicación o en el controlador Mongo para la creación de ID.
    • A diferencia de los ObjectIDs, debido a la forma en que los UUID se dividen , la marca de tiempo no le da un orden natural. Esto puede ser bueno o malo dependiendo de su caso de uso.
    • Incluir marcas de tiempo en sus identificaciones suele ser una mala idea. Usted termina perdiendo el tiempo creado de los documentos en cualquier lugar donde se expone una ID. Para empeorar aún más las cosas, los UUID v1 también codifican un identificador único para la máquina en la que se generan y puede exponer información adicional sobre su infraestructura (por ejemplo, número de servidores). Por supuesto, los ObjectID también codifican una marca de tiempo, por lo que esto también es cierto para ellos.

Encontré estos benchmarks hace un tiempo cuando tuve la misma pregunta. Básicamente, muestran que el uso de Guid en lugar de ObjectId provoca la caída del rendimiento del índice.

De todos modos, le recomendaría que personalice los Puntos de Referencia para imitar su escenario de la vida real específica y vea cómo se ven los números, no se puede confiar al 100% en los Puntos de Referencia genéricos.


El campo _id de MongoDB puede tener cualquier valor que desee siempre que pueda garantizar que es único para la colección. Cuando sus datos ya tienen una clave natural, no hay razón para no usar esto en lugar de los ObjectID generados automáticamente.

Los ObjectID se proporcionan como una solución predeterminada razonable para que el tiempo seguro genere una propia clave única (y para evitar que los principiantes intenten copiar el AUTO INCREMENT de SQL, lo cual es una mala idea en una base de datos distribuida).

Al no usar ObjectIDs, también se pierde otra característica de conveniencia: un ObjectID también incluye una marca de tiempo de Unix cuando se generó, y muchos controladores proporcionan una función para extraerlo y convertirlo en una fecha. Esto puede hacer que un campo de create-date separado sea redundante.

Pero cuando ninguno de los dos le preocupa, puede usar sus UUID como campo _id .