El modelado de datos de aplicaciones para MongoDB debe considerar varios factores operativos que impactan el rendimiento de MongoDB. Por ejemplo, diferentes modelos de datos pueden permitir queries más eficientes, aumentar el rendimiento de las operaciones de inserción y actualización, o distribuir la actividad en un clúster de manera más efectiva.
Al desarrollar un modelo de datos, analiza todos los de tu aplicación operaciones de lectura y escritura en conjunción con las siguientes consideraciones.
Atomicidad
En MongoDB, una operación de escritura es atómica a nivel de un solo documento, incluso si modifica varios documentos incrustados dentro de un mismo documento. Cuando una sola operación de escritura modifica varios documentos (p. ej., db.collection.updateMany()), la modificación de cada documento es atómica, pero la operación como un todo no es atómica.
Modelo de datos incrustado
El modelo de datos integrado combina todos los datos relacionados en un solo documento, en lugar de normalizarlos en varios documentos y colecciones. Este modelo de datos facilita las operaciones atómicas.
Consulta Datos de modelo para operaciones atómicas para ver el modelo de datos de ejemplo que permite actualizaciones atómicas de un solo documento.
Transacción de múltiples documentos
Para los modelos de datos que almacenan referencias entre piezas de datos relacionadas, la aplicación debe emitir operaciones de lectura y guardado separadas para recuperar y modificar estas piezas de datos relacionadas.
Para situaciones que requieren atomicidad de las lecturas y escrituras en varios documentos (en una sola colección o en varias), MongoDB admite transacciones distribuidas, incluidas las transacciones en sets de réplica y clústeres fragmentados.
Para obtener más información, consulta transacciones
Importante
En la mayoría de los casos, una transacción distribuida incurre en un costo de rendimiento mayor que las escrituras de documentos individuales, y la disponibilidad de transacciones distribuidas no debería ser un sustituto para un diseño de esquema efectivo. Para muchos casos, el modelo de datos desnormalizado (documento incrustado y matrices) seguirá siendo óptimo para tus datos y casos de uso. Es decir, en muchos casos, modelar tus datos de forma adecuada minimizará la necesidad de transacciones distribuidas.
Para consideraciones adicionales sobre el uso de transacciones (como el límite de tiempo de ejecución y el límite de tamaño del oplog), consulta también las consideraciones de producción.
particionado
MongoDB utiliza particionado para proporcionar escalado horizontal. Estos clústeres son compatibles con implementaciones con grandes conjuntos de datos y operaciones de alto rendimiento. El particionamiento permite a los usuarios dividir una colección dentro de una base de datos para distribuir los documentos de la colección a través de varias mongod instancias o particiones.
Para distribuir datos y tráfico de la aplicación en una colección particionada, MongoDB utiliza la clave de partición. Seleccionar la clave de partición adecuada tiene importantes implicaciones en el rendimiento y puede permitir o impedir el aislamiento de queries y el aumento de la capacidad de guardar. Aunque más tarde puedes cambiar tu clave de partición, es importante considerar cuidadosamente la elección de esta clave.
Consulte Particionado y Claves de partición para obtener más información.
Indexes
Utilice índices para mejorar el rendimiento de las consultas comunes. Cree índices en los campos que aparecen con frecuencia en las consultas y para todas las operaciones que devuelven resultados ordenados. MongoDB crea automáticamente un índice único en el campo _id.
Al crear índices, ten en cuenta los siguientes comportamientos de los índices:
Cada índice requiere al menos 8 kB de espacio de datos.
Agregar un índice tiene un impacto negativo en el rendimiento de las operaciones de guardar. Para las colecciones con una alta relación de escritura-lectura, los índices son costosos ya que cada inserción también debe actualizar cualquier índice.
Las colecciones con una alta proporción de lecturas respecto a escrituras suelen beneficiarse de índices adicionales. Los índices no afectan a las operaciones de lectura no indexadas.
Cuando está activo, cada índice consume espacio en disco y memoria. Este uso puede ser significativo y debe ser rastreado para la planificación de capacidad, especialmente en lo que respecta al tamaño del conjunto de trabajo.
Consulte Estrategias de indexación para obtener más información sobre los índices, así como Analizar el rendimiento de la query. Además, el perfilador de base de datos de MongoDB puede ayudar a identificar consultas ineficientes.
Gran número de colecciones
En ciertas situaciones, puedes optar por almacenar información relacionada en varias colecciones en lugar de en una sola colección.
Considera una colección de muestra, logs, que almacena documentos de registro para varios entornos y aplicaciones. La colección logs contiene documentos del siguiente formato:
{ log: "dev", ts: ..., info: ... } { log: "debug", ts: ..., info: ...}
Si el número total de documentos es bajo, es posible agrupar los documentos en una colección por tipo. Para los registros, considera mantener colecciones de registros distintas, tales como logs_dev y logs_debug. La colección logs_dev solo contendría los documentos relacionados con el entorno de desarrollo.
Generalmente, tener un gran número de colecciones no supone una pérdida significativa de rendimiento y resulta en un rendimiento muy bueno. Disponer de colecciones diferenciadas es fundamental para el procesamiento por lotes de alto rendimiento.
Cuando utiliza modelos que tienen una gran cantidad de colecciones, tenga en cuenta los siguientes comportamientos:
Cada colección tiene una sobrecarga mínima determinada de unos pocos kilobytes.
Cada índice, incluyendo el índice en
_id, requiere al menos 8 kB de espacio de almacenamiento de datos.Para cada base de datos, un único archivo de namespace (es decir,
<database>.ns) almacena todos los metadatos para esa base de datos, y cada índice y colección tiene su propia entrada en el archivo de namespace. Consulta los límites de longitud de namespace para restricciones específicas.
La colección contiene un gran número de documentos pequeños
Debe considerar la opción de incrustación por motivos de rendimiento si tiene una colección con un gran número de documentos pequeños. Si puedes agrupar estos pequeños documentos según alguna relación lógica y recuperas frecuentemente los documentos mediante este agrupamiento, podrías considerar "consolidar" los pequeños documentos en documentos más grandes que contengan un arreglo de documentos incrustados.
"Consolidar" estos pequeños documentos en agrupamientos lógicos significa que los queries para recuperar un grupo de documentos implican lecturas secuenciales y menos accesos aleatorios al disco. Además, "consolidar" documentos y mover campos comunes al documento más grande beneficia el índice en estos campos. Habría menos copias de los campos comunes y habría menos entradas de claves asociadas en el índice correspondiente. Consulte Índices para obtener más información sobre los índices.
Sin embargo, si a menudo solo necesita recuperar un subconjunto de los documentos dentro del grupo, entonces "recapitular" los documentos puede no proporcionar un mejor rendimiento. Además, si documentos pequeños y separados representan el modelo natural para los datos, deberías mantener ese modelo.
Optimización del almacenamiento para documentos pequeños
Cada documento de MongoDB contiene una cierta cantidad de gastos en general. Estos gastos en general suelen ser insignificantes, pero se vuelven significativos si todos los documentos tienen solo unos pocos bytes, como podría ser el caso si los documentos de tu colección solo tienen uno o dos campos.
Considera las siguientes sugerencias y estrategias para optimizar el uso del almacenamiento para estas colecciones:
Use explícitamente el campo
_id.Los clientes de MongoDB añaden automáticamente un campo
_ida cada documento y generan un ObjectId único de 12bytes para el campo_id. Además, MongoDB siempre indexa el campo_id. Para documentos más pequeños, esto puede representar una cantidad significativa de espacio.Para optimizar el uso del almacenamiento, los usuarios pueden especificar un valor para el campo
_idexplícitamente al insertar documentos en la colección. Esta estrategia permite a las aplicaciones almacenar un valor en el campo_idque habría ocupado espacio en otra parte del documento.Puedes almacenar cualquier valor en el campo
_id, pero como este valor sirve como clave primaria para los documentos de la colección, debe identificarlos de forma única. Si el valor del campo no es único, entonces no puede servir como llave primaria, ya que habría colisiones en la colección.Utilice nombres de campo más cortos.
Nota
Si bien acortar los nombres de campo puede reducir el tamaño de BSON en MongoDB, suele ser más efectivo modificar el modelo general del documento para reducirlo. Acortar los nombres de campo puede reducir la expresividad y no afecta el tamaño de los índices, ya que estos tienen una estructura predefinida que no incorpora nombres de campo.
MongoDB almacena todos los nombres de campos en cada documento. Para la mayoría de los documentos, esto representa una pequeña fracción del espacio utilizado por un documento; sin embargo, para documentos pequeños los nombres de campo pueden representar una proporción considerablemente grande de espacio. Considere una colección de documentos pequeños que se asemejan a lo siguiente:
{ last_name : "Smith", best_score: 3.9 } Si acortas el campo llamado
last_namealnamey el campo llamadobest_scoreascore, como se indica a continuación, podrías ahorrar 9 bytes por documento.{ lname : "Smith", score : 3.9 } documento incrustado.
En algunos casos, puedes querer insertar documentos dentro de otros documentos y ahorrar en los costes por documento. Ver La colección contiene un gran número de documentos pequeños.
Optimizar el modelo orientado a documentos.
Gestión del ciclo de vida de los datos
Las decisiones de modelado de datos deben considerar la gestión del ciclo de vida de los datos.
La funcionalidad de Time to Live o TTL de las colecciones elimina los documentos tras un período de tiempo. Considera usar la funcionalidad TTL si tu aplicación requiere que algunos datos persistan en la base de datos durante un periodo limitado de tiempo.
Además, si tu aplicación sólo utiliza documentos insertados recientemente, considera colección con tamaño fijo. Las colecciones acotadas proporcionan una gestión primero en entrar, primero en salir (FIFO) de los documentos insertados y admiten eficazmente las operaciones que insertan y leen documentos según el orden de inserción.