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

Planificación y gestión de esquemas en MongoDB (aunque no tenga esquemas)

Cuando se introdujo MongoDB, la característica principal destacada fue su capacidad de ser "sin esquema". ¿Qué significa? Significa que uno puede almacenar documentos JSON, cada uno con una estructura diferente, en la misma colección. Esto está muy bien. Pero el problema comienza cuando necesita recuperar los documentos. ¿Cómo saber si un documento recuperado tiene una determinada estructura o si contiene un campo en particular o no? Tienes que recorrer todos los documentos y buscar ese campo en particular. Por eso es útil planificar cuidadosamente el esquema MongoDB, especialmente para las aplicaciones grandes.

Cuando se trata de MongoDB, no hay una forma específica de diseñar el esquema. Todo depende de su aplicación y de cómo su aplicación va a utilizar los datos. Sin embargo, existen algunas prácticas comunes que puede seguir al diseñar el esquema de su base de datos. Aquí, discutiré estas prácticas y sus ventajas y desventajas.

Modelado uno a pocos (incrustación)

Este diseño es un muy buen ejemplo de incrustación de documentos. Considere este ejemplo de una colección Person para ilustrar este modelo.

{
  name: "Amy Cooper",
  hometown: "Seoul",
  addresses: [
    { city: 'New York', state: 'NY', cc: 'USA' },
    { city: 'Jersey City', state: 'NJ', cc: 'USA' }
  ]
}

Ventajas:

  • Puedes obtener toda la información en una sola consulta.

Contras:

  • Los datos incrustados dependen completamente del documento principal. No puede buscar los datos incrustados de forma independiente.
  • Considere el ejemplo en el que está creando un sistema de seguimiento de tareas utilizando este enfoque. Luego, incrustará todas las tareas específicas de una persona en la colección Persona. Si desea activar una consulta como:Muéstrame todas las tareas que tienen mañana como fecha límite. Esto puede ser muy difícil, a pesar de que es una consulta simple. En este caso, debe considerar otros enfoques.

Modelado de uno a muchos (referencia)

En este tipo de modelado, el documento principal contendrá el Id. de referencia (ObjectID) de los documentos secundarios. Debe usar combinaciones de nivel de aplicación (combinar dos documentos después de recuperarlos de la base de datos en el nivel de aplicación) para recuperar documentos, por lo que no hay combinaciones de nivel de base de datos. Por lo tanto, se reducirá la carga en una base de datos. Considere este ejemplo:

// Parts collection
{
  _id: ObjectID(1234),
  partno: '1',
  name: ‘Intel 100 Ghz CPU',
  qty: 100,
  cost: 1000,
  price: 1050
}
// Products collection
{
  name: 'Computer WQ-1020',
  manufacturer: 'ABC Company',
  catalog_number: 1234,
  parts: [
    ObjectID(‘1234’), <- Ref. for Part No: 1
    ObjectID('2345'),
    ObjectID('3456')
  ]
}

Suponga que cada producto puede tener varios miles de partes asociadas. Para este tipo de base de datos, la referencia es el tipo ideal de modelado. Pones los identificadores de referencia de todas las piezas asociadas en el documento del producto. Luego puede usar uniones de nivel de aplicación para obtener las piezas para un producto en particular.

Ventajas:

  • En este tipo de modelado, cada parte es un documento separado para que pueda aplicar todas las consultas relacionadas con la parte en estos documentos. No es necesario depender del documento principal.
  • Muy fácil de realizar operaciones CRUD (Crear, Leer, Actualizar, Escribir) en cada documento de forma independiente.

Contras:

  • Un gran inconveniente de este método es que debe realizar una consulta adicional para obtener los detalles de la pieza. Para que pueda realizar uniones a nivel de aplicación con el documento del producto para obtener el conjunto de resultados necesario. Por lo tanto, puede provocar una caída en el rendimiento de la base de datos.
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

Modelado de uno a millones (referencia de padres)

Cuando necesita almacenar toneladas de datos en cada documento, no puede usar ninguno de los enfoques anteriores porque MongoDB tiene un límite de tamaño de 16 MB por documento. Un ejemplo perfecto de este tipo de escenario puede ser un sistema de registro de eventos que recopila registros de diferentes tipos de máquinas y los almacena en colecciones de registros y máquinas.

Aquí, ni siquiera puede pensar en usar el enfoque de incrustación que almacena toda la información de registros para una máquina en particular en un solo documento. Esto se debe a que, en solo unas pocas horas, el tamaño del documento superará los 16 MB. Incluso si solo almacena los identificadores de referencia de todos los documentos de registro, seguirá agotando el límite de 16 MB porque algunas máquinas pueden generar millones de mensajes de registro en un solo día.

Entonces, en este caso, podemos usar el enfoque de referencia principal. En este enfoque, en lugar de almacenar los identificadores de referencia de los documentos secundarios en el documento principal, almacenaremos el identificador de referencia del documento principal en todos los documentos secundarios. Entonces, para nuestro ejemplo, almacenaremos ObjectID de la máquina en documentos de Logs. Considere este ejemplo:

// Machines collection
{
  _id : ObjectID('AAA'),
  name : 'mydb.example.com',
  ipaddr : '127.66.0.4'
}
// Logs collection
{
  time : ISODate("2015-09-02T09:10:09.032Z"),
  message : 'WARNING: CPU usage is critical!',
  host: ObjectID('AAA')       -> references Machine document
}

Suponga que desea encontrar los 3000 registros más recientes de la máquina 127.66.0.4:

machine = db.machines.findOne({ipaddr : '127.66.0.4'});
msgs = db.logmsg.find({machine: machine._id}).sort({time : -1}).limit(3000).toArray()

Referencia bidireccional

En este enfoque, almacenamos las referencias en ambos lados, lo que significa que la referencia del padre se almacenará en el documento secundario y la referencia del hijo se almacenará en el documento principal. Esto hace que la búsqueda sea relativamente fácil en el modelado de uno a muchos. Por ejemplo, podemos buscar tanto en documentos principales como de tareas. Por otro lado, este enfoque requiere dos consultas separadas para actualizar un documento.

// person
{
  _id: ObjectID("AAAA"),
  name: "Bear",
  tasks [ 
    ObjectID("AAAD"),
    ObjectID("ABCD"), -> Reference of child document
    ObjectID("AAAB")
  ]
}
// tasks
{
  _id: ObjectID("ABCD"),
  description: "Read a Novel",
  due_date:  ISODate("2015-11-01"),
  owner: ObjectID("AAAA") -> Reference of parent document
}

Conclusión

Al final, todo depende de los requisitos de su aplicación. Puede diseñar el esquema MongoDB de la manera que sea más beneficiosa para su aplicación y le brinde un alto rendimiento. Estas son algunas consideraciones resumidas que puede tener en cuenta al diseñar su esquema.

  1. Diseñe el esquema en función de los patrones de acceso a datos de su aplicación.
  2. No es necesario incrustar documentos cada vez. Combine documentos solo si los va a usar juntos.
  3. Considere la posibilidad de duplicar los datos porque hoy en día el almacenamiento es más económico que la potencia informática.
  4. Optimizar el esquema para casos de uso más frecuentes.
  5. Las matrices no deben crecer fuera de los límites. Si hay más de un par de cientos de documentos secundarios, no los inserte.
  6. Prefiera las uniones a nivel de aplicación a las uniones a nivel de base de datos. Con la indexación adecuada y el uso adecuado de los campos de proyección, puede ahorrarle mucho tiempo.