relacionar - mongodb tutorial español
Demasiada duplicación de datos en mongodb? (2)
Soy nuevo en todo este tema de NOSQL y recientemente me he sentido intrigado con mongoDB. Estoy creando un nuevo sitio web desde cero y decidí ir con MONGODB / NORM (para C #) como mi única base de datos. He estado leyendo mucho sobre cómo diseñar correctamente su base de datos de modelos de documentos y creo que, en general, mi diseño ha funcionado bastante bien. Llevo unos 6 meses en mi nuevo sitio y estoy empezando a ver problemas con la duplicación / sincronización de datos con los que tengo que lidiar una y otra vez. Según lo que leí, esto se espera en el modelo de documento, y para el rendimiento tiene sentido. IE inserta objetos incrustados en su documento para que sea rápido de leer, sin uniones; pero, por supuesto, no siempre se puede insertar, por lo que mongodb tiene este concepto de una DbReference que es básicamente análogo a una clave externa en DB relacionales.
Así que aquí hay un ejemplo: tengo usuarios y eventos; ambos obtienen su propio documento, los usuarios asisten a eventos, los eventos tienen usuarios asistentes. Decidí incluir una lista de eventos con datos limitados en los objetos del usuario. Integré una lista de usuarios también en los objetos de evento como sus "asistentes". El problema aquí es que ahora debo mantener a los usuarios sincronizados con la lista de usuarios que también está integrada en el objeto de evento. Mientras lo leo, este parece ser el enfoque preferido, y la forma NOSQL de hacer las cosas. La recuperación es rápida, pero el inconveniente es que cuando actualizo el documento principal del usuario, también debo ingresar a los objetos del evento, posiblemente encontrar todas las referencias a ese usuario y actualizarlo también.
Entonces, la pregunta que tengo es si este es un problema bastante común que las personas deben enfrentar. ¿Cuánto tiene que pasar este problema antes de comenzar a decir "tal vez la estrategia NOSQL no se ajusta a lo que trato de hacer aquí"? ¿Cuándo la ventaja de rendimiento de no tener uniones se convierte en una desventaja porque estás teniendo dificultades para mantener los datos sincronizados en los objetos incrustados y hacer varias lecturas al DB para hacerlo?
Bueno, esa es la compensación con las tiendas de documentos. Puede almacenar de forma normalizada como cualquier RDMS estándar, y debe esforzarse por la normalización tanto como sea posible. Es solo cuando se produce un impacto en el rendimiento que debe romper la normalización y aplanar sus estructuras de datos. La compensación es la eficiencia de lectura frente al costo de actualización.
Mongo tiene índices realmente eficientes que pueden hacer que la normalización sea más fácil como un RDMS tradicional (la mayoría de las tiendas de documentos no te dan esto gratis, por lo que Mongo es más un híbrido que una tienda de documentos pura). Al usar esto, puede hacer una colección de relaciones entre usuarios y eventos. Es análogo a una tabla sustituta en un almacén de datos tabular. Indexe los campos de eventos y usuarios, y debería ser bastante rápido y lo ayudará a normalizar mejor sus datos.
Me gusta trazar la eficiencia de nivelar una estructura y mantenerla normalizada cuando se trata del tiempo que me lleva actualizar los datos de los registros y leer lo que necesito en una consulta. Puedes hacerlo en términos de la notación O grande, pero no tienes que ser tan elegante. Simplemente coloque algunos números en papel en función de unos pocos casos de uso con diferentes modelos de datos y tenga una buena impresión acerca de cuánto trabajo se requiere.
Básicamente, lo que hago es primero tratar de predecir la probabilidad de cuántas actualizaciones tendrá un registro vs. la frecuencia con la que se lee. Luego trato de predecir cuál es el costo de una actualización frente a una lectura cuando está normalizada o aplanada (o quizás una combinación parcial de las dos que puedo concebir ... muchas opciones de optimización). Entonces puedo juzgar los ahorros de mantenerlo plano frente al costo de construir los datos de fuentes normalizadas. Una vez que tracé todas las variables, si el ahorro de mantenerlo plano me ahorra un montón, entonces lo mantendré plano.
Algunos consejos:
- Si necesita que las búsquedas rápidas sean rápidas y atómicas (perfectamente actualizadas), es posible que desee un favor, una solución en la que favorezca el aplanamiento por sobre la normalización y el éxito en la actualización.
- Si necesita que la actualización sea rápida, y acceda de inmediato, favorezca la normalización.
- Si necesita búsquedas rápidas pero no requiere datos perfectamente actualizados, considere construir sus datos normalizados en trabajos por lotes (usando map / reducir posiblemente).
- Si sus consultas necesitan ser rápidas, y las actualizaciones son raras, y no requieren necesariamente que su actualización esté accesible de inmediato o que requieran un bloqueo de nivel de transacción que haya pasado el 100% del tiempo (para garantizar que su actualización se haya escrito en el disco), usted puede considerar escribir sus actualizaciones en una cola procesándolas en segundo plano. (En este modelo, probablemente tendrá que lidiar con la resolución de conflictos y la reconciliación más adelante).
- Perfil de diferentes modelos. Construya una capa de abstracción de consulta de datos (como un ORM de una manera) en su código para que pueda refactorizar la estructura de su almacén de datos más adelante.
Hay muchas otras ideas que puede emplear. Hay muchos blogs geniales en línea que entran en él como highscalabilty.org y se aseguran de que entiendas el teorema de CAP.
Considere también una capa de almacenamiento en caché, como Redis o Memcache. Pondré uno de esos productos en frente de mi capa de datos. Cuando consulto mongo (que está almacenando todo normalizado), uso los datos para construir una representación aplanada y almacenarla en el caché. Cuando actualizo los datos, anularé cualquier dato en el caché que haga referencia a lo que estoy actualizando. (Aunque debe tomarse el tiempo necesario para invalidar los datos y hacer un seguimiento de los datos en la memoria caché que se actualiza teniendo en cuenta sus factores de escala). Alguien dijo una vez: "Las dos cosas más difíciles en Informática son nombrar cosas y la invalidación de la memoria caché".
¡Espero que ayude!
Intente agregar un IList de tipo propiedad UserEvent a su objeto User. No especificó demasiado acerca de cómo está diseñado su modelo de dominio. Consulte el grupo NoRM http://groups.google.com/group/norm-mongodb/topics para ver ejemplos.