Disenando Esquemas de MongoDB que Escalan
Por Carlos Diaz · 21 de mayo de 2024 · 3 min de lectura
El error mas comun que veo con MongoDB es tratarlo como una base de datos relacional con otra sintaxis: un documento por entidad, referencias estilo llave foranea por todos lados, y un esquema que imita un diagrama entidad-relacion. Ese enfoque desecha la razon de usar MongoDB en primer lugar y reproduce los problemas de las bases de datos relacionales sin las herramientas relacionales para resolverlos.
La pregunta correcta para empezar no es 'cuales son mis entidades' sino 'que lee junto mi aplicacion, y con que frecuencia escribe cada pieza.' Los datos que siempre se leen juntos usualmente deberian vivir en el mismo documento - un plan de cuidados y la lista pequena y acotada de sus actualizaciones recientes, por ejemplo - porque incrustar convierte lo que seria un join en una sola lectura. Los datos que crecen sin limite, o que multiples partes no relacionadas del sistema necesitan referenciar de forma independiente, deberian ser una coleccion separada con una referencia, porque incrustarlos eventualmente rebasaria los limites de tamano de documento o te obligaria a reescribir un documento gigante por una actualizacion pequena.
La consistencia entre multiples documentos es donde los equipos se sorprenden. Las transacciones de MongoDB existen y funcionan, pero recurrir a ellas por todos lados suele ser una senal de que el limite del esquema esta mal: si dos piezas de datos necesitan cambiar atomicamente juntas en cada escritura, eso suele ser una senal de que pertenecen al mismo documento en lugar de necesitar una transaccion para mantenerlas consistentes entre dos.
La evolucion de esquemas en una base de datos sin esquema es enganosamente dificil, precisamente porque nada la impone. Los documentos antiguos no ganan automaticamente un campo nuevo solo porque el codigo nuevo lo espera, lo que significa que cada ruta de lectura tiene que manejar defensivamente documentos escritos por codigo de tres versiones atras, o corres una migracion explicita. Me he movido hacia escribir esquemas de validacion ligeros a nivel de aplicacion especificamente para que la desviacion de esquema se convierta en un error visible y ruidoso en lugar de un bug silencioso con forma de null-pointer tres meses despues.
Los indices no son algo que agregas despues cuando las cosas se ponen lentas, son parte del diseno del esquema mismo. Un indice compuesto que coincide con la forma real de tus consultas, un indice parcial que solo cubre el subconjunto de documentos que realmente consultas, y un indice TTL para todo lo que deba expirar automaticamente haran mas por tu rendimiento en produccion que casi cualquier otro cambio individual, y la salida explain del pipeline de agregacion te dira exactamente donde debe ir el siguiente.
Puntos Clave
- Modela los esquemas segun los patrones de acceso primero, las entidades despues.
- Incrusta relaciones acotadas de uno-a-pocos; referencia los datos que crecen sin limite.
- Recurrir a transacciones multi-documento por todos lados suele ser senal de que el limite del esquema esta mal.
- La validacion ligera a nivel de aplicacion convierte la desviacion silenciosa de esquema en un error visible.
- Los indices compuestos, parciales y TTL deben reflejar tus patrones de consulta reales, no ser un anadido tardio.

