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

MongoDB (noSQL) cuándo dividir colecciones

Como ya se escribió, no hay reglas como la segunda forma normal para SQL.

Sin embargo, existen algunas mejores prácticas y errores comunes relacionados con la optimización para MongoDB que enumeraré aquí.

Uso excesivo de incrustaciones

El límite de BSON

Contrariamente a la creencia popular, no hay nada malo con las referencias. Suponga que tiene una biblioteca de libros y desea realizar un seguimiento de los alquileres. Podrías empezar con un modelo como este

{
  // We use ISBN for its uniqueness 
  _id: "9783453031456"
  title: "Schismatrix",
  author: "Bruce Sterling",
  rentals: [
    {
      name:"Markus Mahlberg,
      start:"2015-05-05T03:22:00Z",
      due:"2015-05-12T12:00:00Z"
    }
  ]
}

Si bien hay varios problemas con este modelo, el más importante no es obvio:habrá un número limitado de alquileres por el hecho de que los documentos BSON tienen un límite de tamaño de 16 MB.

El problema de la migración de documentos

El otro problema con el almacenamiento de alquileres en una matriz sería que esto provocaría migraciones de documentos relativamente frecuentes, lo cual es una operación bastante costosa. Los documentos BSON nunca se dividen en particiones y se crean con un espacio adicional asignado por adelantado que se usa cuando crecen. Este espacio adicional se llama relleno. Cuando se excede el relleno, el documento se mueve a otra ubicación en los archivos de datos y se asigna un nuevo espacio de relleno. Por lo tanto, las adiciones frecuentes de datos provocan migraciones frecuentes de documentos. Por lo tanto, es una buena práctica evitar las actualizaciones frecuentes que aumentan el tamaño del documento y utilizar referencias en su lugar.

Entonces, para el ejemplo, cambiaríamos nuestro modelo único y crearíamos uno segundo. Primero, el modelo para el libro

{
  _id: "9783453031456",
  title:"Schismatrix",
  author: "Bruce Sterling"
}

El segundo modelo para el alquiler se vería así

{
  _id: new ObjectId(),
  book: "9783453031456",
  rentee: "Markus Mahlberg",
  start: ISODate("2015-05-05T03:22:00Z"),
  due: ISODate("2015-05-05T12:00:00Z"),
  returned: ISODate("2015-05-05T11:59:59.999Z")
}

El mismo enfoque, por supuesto, podría utilizarse para el autor o el arrendatario.

El problema de la sobrenormalización

Miremos hacia atrás un tiempo. Un desarrollador identificaría las entidades involucradas en un caso de negocio, definiría sus propiedades y relaciones, escribiría las clases de entidad correspondientes, se golpearía la cabeza contra la pared durante unas horas para lograr que el triple interno-externo-encima-y-más-allá JOIN funcione requerido para el caso de uso y todos vivieron felices para siempre. Entonces, ¿por qué usar NoSQL en general y MongoDB en particular? Porque nadie vivió feliz para siempre. Este enfoque escala horriblemente y casi exclusivamente la única forma de escalar es vertical.

Pero la principal diferencia de NoSQL es que modela sus datos de acuerdo con las preguntas que necesita que le respondan.

Dicho esto, veamos una relación n:m típica y tomemos la relación entre autores y libros como ejemplo. En SQL, tendría 3 tablas:dos para sus entidades (libros y autores ) y otra para la relación (¿Quién es el autor de qué libro? ). Por supuesto, podría tomar esas tablas y crear sus colecciones equivalentes. Pero, dado que no hay JOIN en MongoDB, necesitaría tres consultas (una para la primera entidad, una para sus relaciones y otra para las entidades relacionadas) para encontrar los documentos relacionados de una entidad. Esto no tendría sentido, ya que el enfoque de tres tablas para las relaciones n:m se inventó específicamente para superar los esquemas estrictos que imponen las bases de datos SQL. Dado que MongoDB tiene un esquema flexible, la primera pregunta sería dónde almacenar la relación, manteniendo los problemas. derivados del uso excesivo de la incrustación en la mente. Dado que un autor puede escribir bastantes libros en los próximos años, pero la autoría de un libro rara vez cambia, si es que cambia, la respuesta es simple:almacenamos los autores como una referencia a los autores en los datos de los libros

{
  _id: "9783453526723",
  title: "The Difference Engine",
  authors: ["idOfBruceSterling","idOfWilliamGibson"]
}

Y ahora podemos encontrar a los autores de ese libro haciendo dos consultas:

var book = db.books.findOne({title:"The Difference Engine"})
var authors = db.authors.find({_id: {$in: book.authors})

Espero que lo anterior le ayude a decidir cuándo "dividir" realmente sus colecciones y sortear las trampas más comunes.

Conclusión

En cuanto a sus preguntas, aquí están mis respuestas

  1. Como se escribió antes:No , pero tener en cuenta las limitaciones técnicas debería darle una idea de cuándo podría tener sentido.
  2. No está mal, siempre y cuando se ajuste a su(s) caso(s) de uso . Si tiene una categoría dada y su _id , es fácil encontrar los productos relacionados. Al cargar el producto, puede obtener fácilmente las categorías a las que pertenece, incluso de manera eficiente, como _id está indexado de forma predeterminada.
  3. Todavía tengo que encontrar un caso de uso que no se pueda hacer con MongoDB, aunque algunas cosas pueden complicarse un poco con MongoDB. Lo que debe hacer en mi humilde opinión es tomar la suma de sus requisitos funcionales y no funcionales y verificar si las ventajas superan las desventajas. Mi regla general:si uno de "escalabilidad" o "alta disponibilidad/conmutación por error automática" está en su lista de requisitos, MongoDB vale más que una mirada.