sql >> Base de Datos >  >> NoSQL >> MongoDB

Factores operativos a considerar durante el modelado de datos de MongoDB

En mi blog anterior, Cómo usar el modelado de datos de MongoDB para mejorar las operaciones de rendimiento, discutimos los 2 principales enfoques de relaciones de modelado de datos, es decir, la incorporación y la referencia. La escalabilidad de MongoDB depende bastante de su arquitectura y, para ser más específicos, del modelado de datos. Al diseñar un DBM NoSQL, el punto principal a considerar es garantizar documentos sin esquema además de una pequeña cantidad de colecciones con el fin de facilitar el mantenimiento. Se recomienda buena integridad de datos, adoptando la validación de datos a través de algunas reglas definidas antes del almacenamiento. La arquitectura y el diseño de una base de datos deben normalizarse y descomponerse en múltiples colecciones pequeñas como una forma de evitar la repetición de datos, mejorar la integridad de los datos y facilitar los patrones de recuperación. Con esto en su lugar, puede mejorar la coherencia de los datos, la atomicidad, la durabilidad y la integridad de su base de datos.

El modelado de datos no es una tarea de último momento en la fase de desarrollo de una aplicación, sino una consideración inicial, ya que muchas facetas de la aplicación se realizan realmente durante la etapa de modelado de datos. En este artículo, analizaremos qué factores deben considerarse durante el modelado de datos y veremos cómo afectan el rendimiento de una base de datos en general.

Muchas veces necesitará implementar un clúster de su base de datos como una forma de aumentar la disponibilidad de los datos. Con un modelo de datos bien diseñado, puede distribuir actividades a un clúster fragmentado de manera más efectiva, por lo tanto, reducir las operaciones de rendimiento dirigidas a una sola instancia de mongod. Los principales factores a considerar en el modelado de datos incluyen:

  1. Escalabilidad
  2. Atomicidad
  3. Rendimiento y uso de datos
  4. fragmentación
  5. Indización
  6. Optimización del almacenamiento
  7. Estructura y crecimiento del documento
  8. Ciclo de vida de los datos

1. Escalabilidad

Este es un aumento en la carga de trabajo de una aplicación impulsada por un mayor tráfico. Muchas aplicaciones siempre tienen una expectativa en el aumento del número de sus usuarios. Cuando hay tantos usuarios atendidos por una sola instancia de base de datos, el rendimiento no siempre cumple con las expectativas. Como administrador de la base de datos, tiene el mandato de diseñar este DBM de manera que las colecciones y las entidades de datos se modelen en función de las demandas presentes y futuras de la aplicación. La estructura de la base de datos generalmente debe estar presentable para facilitar el proceso de replicación y fragmentación. Cuando tiene más fragmentos, las operaciones de escritura se distribuyen entre estos fragmentos de modo que para cualquier actualización de datos, se realiza dentro del fragmento que contiene esos datos en lugar de buscar en un solo conjunto grande de datos para realizar una actualización.

2. Atomicidad

Esto se refiere al éxito o fracaso de una operación como una sola unidad. Por ejemplo, puede tener una operación de lectura que involucre una operación de clasificación después de obtener el resultado. Si la operación de clasificación no se maneja correctamente, toda la operación no pasará a la siguiente etapa.

Las transacciones atómicas son series de operaciones que no son ni divisibles ni reducibles, por lo tanto, ocurren como entidades únicas o fallan como operaciones únicas. Las versiones de MongoDB anteriores a la 4.0 admiten operaciones de escritura como procesos atómicos en un solo nivel de documento. Con la versión 4.0, ahora se pueden implementar transacciones de varios documentos. Un modelo de datos que mejora las operaciones atómicas tiende a tener un gran rendimiento en términos de latencia. La latencia es simplemente la duración dentro de la cual se envía una solicitud de operación y cuando se devuelve una respuesta de la base de datos. Para ser seco, es fácil actualizar los datos que están incrustados en un solo documento en lugar de uno al que se hace referencia.

Consideremos, por ejemplo, el conjunto de datos a continuación

{
    childId : "535523",
    studentName : "James Karanja",
    parentPhone : 704251068,
    age : 12,
    settings : {
        location : "Embassy",
        address : "420 01",
        bus : "KAZ 450G",
        distance : "4"
      }
}

Si queremos actualizar la edad aumentándola en 1 y cambiar la ubicación a Londres podríamos hacer:

db.getCollection(‘students’).update({childId: 535523},{$set:{'settings.location':'London'}, $inc:{age:1}}).

Si, por ejemplo, falla la operación $set, automáticamente no se implementará la operación $inc y, en general, falla toda la operación.

Por otro lado, consideremos datos referenciados, de modo que hay 2 colecciones, una para estudiante y otra para configuración.

Colección de estudiantes

{
    childId : "535523",
    studentName : "James Karanja",
    parentPhone : 704251068,
    age : 12
}

Colección de configuraciones

{
  childId : "535523",  
  location : "Embassy",
  address : "420 01",
  bus : "KAZ 450G",
  distance : "4"
}

En este caso, puede actualizar los valores de edad y ubicación con operaciones de escritura separadas, es decir,

db.getCollection(‘students’).update({childId: 535523},{$inc:{age:1}})
db.getCollection('settings’).update({childId: 535523 } , {$set: { 'settings.location':'London'}})

Si una de las operaciones falla, no necesariamente afecta a la otra ya que se realizan como entidades diferentes.

Transacciones para varios documentos

Con MongoDB versión 4.0, ahora puede realizar múltiples transacciones de documentos para conjuntos de réplicas. Esto mejora el rendimiento ya que las operaciones se envían a varias colecciones, bases de datos y documentos para un procesamiento rápido. Cuando se ha confirmado una transacción, los datos se guardan, mientras que si algo sale mal y una transacción falla, los cambios realizados se descartan y, por lo general, la transacción se cancelará. No se actualizarán los conjuntos de réplicas durante la transacción, ya que la operación solo es visible en el exterior cuando la transacción está completamente confirmada.

Por mucho que pueda actualizar varios documentos en varias transacciones, viene con un revés de rendimiento reducido en comparación con las escrituras de un solo documento. Además, este enfoque solo es compatible con el motor de almacenamiento WiredTiger, por lo que es una desventaja para los motores de almacenamiento In-Memory y MMAPv1.

3. Rendimiento y uso de datos

Las aplicaciones están diseñadas de manera diferente para cumplir con diferentes propósitos. Hay algunos que solo sirven para los datos actuales, como las aplicaciones de noticias meteorológicas. Dependiendo de la estructura de una aplicación, uno debería poder diseñar una base de datos óptima correspondiente para servir el caso de uso requerido. Por ejemplo, si uno desarrolla una aplicación que obtiene los datos más recientes de la base de datos, usar una colección limitada será la mejor opción. Una colección limitada mejora la operación de alto rendimiento al igual que un búfer, de modo que cuando se explota el espacio asignado, los documentos más antiguos se sobrescriben y los documentos se pueden recuperar en el orden en que se insertaron. Teniendo en cuenta la recuperación del orden de inserción, no será necesario utilizar la indexación y la ausencia de una sobrecarga de índice mejorará igualmente el rendimiento de escritura. Con una colección limitada, los datos asociados son bastante pequeños, ya que se pueden mantener dentro de la RAM durante algún tiempo. Los datos temporales en este caso se almacenan en la memoria caché, que se lee más que escribir, por lo que la operación de lectura es bastante rápida. Sin embargo, la colección limitada tiene algunas desventajas, como que no puede eliminar un documento a menos que elimine toda la colección, cualquier cambio en el tamaño de un documento fallará en la operación y, por último, no es posible fragmentar una colección limitada.

Se integran diferentes facetas en el modelado de datos de una base de datos dependiendo de las necesidades de uso. Como se ve, las aplicaciones de informes tenderán a ser más intensivas en lectura, por lo que el diseño debe mejorar el rendimiento de lectura.

4. Fragmentación

El rendimiento a través del escalado horizontal se puede mejorar mediante la fragmentación, ya que las cargas de trabajo de lectura y escritura se distribuyen entre los miembros del clúster. La implementación de un grupo de fragmentos tiende a dividir la base de datos en múltiples colecciones pequeñas con documentos distribuidos según alguna clave de fragmento. Debe seleccionar una clave de fragmento adecuada que pueda evitar el aislamiento de consultas además de aumentar la capacidad de escritura. Una mejor selección generalmente involucra un campo que está presente en todos los documentos dentro de la colección de destino. Con la fragmentación, aumenta el almacenamiento ya que, a medida que crecen los datos, se establecen más fragmentos para contener un subconjunto de este clúster.

5. Indexación

La indexación es uno de los mejores enfoques para mejorar la carga de trabajo de escritura, especialmente cuando los campos aparecen en todos los documentos. Al realizar la indexación, se debe considerar que cada índice requerirá 8 KB de espacio de datos. Además, cuando el índice está activo, consumirá algo de espacio en disco y memoria, por lo que se debe realizar un seguimiento para planificar la capacidad.

Varios nueves Conviértase en un administrador de bases de datos de MongoDB - Llevando MongoDB a la producción Obtenga información sobre lo que necesita saber para implementar, monitorear, administrar y escalar MongoDBDescargar gratis

6. Optimización de almacenamiento

Muchos documentos pequeños dentro de una colección tenderán a ocupar más espacio que cuando tiene algunos documentos con documentos subincrustados. Al modelar, por lo tanto, se deben agrupar los datos relacionados antes del almacenamiento. Con unos pocos documentos, una operación de base de datos se puede realizar con pocas consultas, por lo tanto, se reduce el acceso aleatorio al disco y habrá menos entradas clave asociadas en el índice correspondiente. Las consideraciones en este caso, por lo tanto, serán:utilizar incrustaciones para tener menos documentos, lo que a su vez reduce la sobrecarga por documento. Use nombres de campo más cortos si hay menos campos involucrados en una colección para no hacer que la sobrecarga del documento sea significativa. Los nombres de campo más cortos reducen la expresividad, es decir,

{ Lname : "Briston", score : 5.9 }

ahorrará 9 bytes por documento en lugar de usar

{ last_name : "Briston", high_score: 5.9 }

Utilice el campo _id de forma explícita. De manera predeterminada, los clientes de MongoDB agregan un campo _id a cada documento asignando un ObjectId único de 12 bytes para este campo. Además, se indexará el campo _id. Si los documentos son bastante pequeños, este escenario representará una cantidad significativa de espacio en el número total de documentos. Para optimizar el almacenamiento, puede especificar el valor del campo _id de forma explícita al insertar documentos en una colección. Sin embargo, asegúrese de que el valor se identifique de forma única porque sirve como clave principal para los documentos de la colección.

7. Estructura y crecimiento del documento

Esto sucede como resultado de la operación de inserción en la que los subdocumentos se insertan en un campo de matriz o cuando se agregan nuevos campos a un documento existente. El crecimiento del documento tiene algunos contratiempos, es decir, para una colección limitada, si se modifica el tamaño, la operación fallará automáticamente. Para un motor de almacenamiento MMAPv1, las versiones anteriores a la 3.0 reubicarán el documento en el disco si se excede el tamaño del documento. Sin embargo, versiones posteriores a partir de la 3.0, existe un concepto de Power of 2 Sized Allocations que reduce las posibilidades de dichas reasignaciones y permite la reutilización efectiva del espacio de registro liberado. Si espera que sus datos crezcan, es posible que desee refactorizar su modelo de datos para usar referencias entre datos en distintos documentos en lugar de usar un modelo de datos no normalizado. Para evitar el crecimiento de documentos, también puede considerar usar una estrategia de asignación previa.

8. Ciclo de vida de los datos

Para una aplicación que usa solo los documentos insertados recientemente, considere usar una colección limitada cuyas características se han discutido anteriormente.

También puede configurar la función Tiempo de vida para su colección. Esto es bastante aplicable para tokens de acceso en la función de restablecimiento de contraseña para una aplicación.

Tiempo de vida (TTL)

Esta es una configuración de recopilación que hace posible que mongod elimine datos automáticamente después de una duración específica. De forma predeterminada, este concepto se aplica a los datos de eventos, registros e información de sesiones generados por máquinas que deben persistir durante un período de tiempo limitado.

Ejemplo:

db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

Creamos un índice createdAt y especificamos un valor de expireAfterSeconds de 3600, que es 1 hora después de la hora de creación. Ahora si insertamos un documento como:

db.log_events.insert( {
   "createdAt": new Date(),
   "logEvent": 2,
   "logMessage": "This message was recorded."
} )

Este documento se eliminará después de 1 hora desde el momento de la inserción.

También puede establecer una hora específica de reloj cuando desea que se elimine el documento. Para hacerlo, primero cree un índice, es decir:

db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )

Ahora podemos insertar un documento y especificar el momento en que debe eliminarse.

db.log_events.insert( {
   "expireAt": new Date(December 12, 2018 18:00:00'),
   "logEvent": 2,
   "logMessage": "Success!"
} )

Este documento se eliminará automáticamente cuando el valor expireAt sea anterior al número de segundos especificado en expireAfterSeconds, es decir, 0 en este caso.

Conclusión

El modelado de datos es una tarea espaciosa para cualquier diseño de aplicación con el fin de mejorar el rendimiento de su base de datos. Antes de insertar datos en su base de datos, considere las necesidades de la aplicación y cuáles son los mejores patrones de modelo de datos que debe implementar. Además, las facetas importantes de las aplicaciones no pueden realizarse hasta la implementación de un modelo de datos adecuado.