2012-07-16 12 views
8

Me he estado preguntando sobre la estructura de documento ideal para la máxima eficiencia de consulta para diversas situaciones y hay una sobre la que quiero preguntar. Debo realmente confirmar que realmente no sé cómo se comporta MongoDB en la memoria en este tipo de caso específico. Déjame darte un escenario hipotético.¿Qué es una buena estructura de documentos MongoDB para la consulta más eficiente de seguidores de usuarios/followees?

Imagine un sistema al estilo Twitter de seguidores y seguidores. Después de una mirada superficial es cierto, las principales opciones parecen ser:

  1. En cada documento de usuario, una matriz de "seguidores" que contiene referencias a todos los documentos de otros usuarios que siguen. Los seguidores se encuentran al encontrar nuestro usuario actual en la matriz "user.followers" de otros usuarios. La desventaja principal parece ser la posible sobrecarga de consultas de la búsqueda de seguidores. Además, para una consulta específica para los contenidos de "usuario.seguidores", ¿accede MongoDB al campo requerido en los documentos de los usuarios, o se encuentra el documento de usuario completo y luego se buscan los valores de campo requeridos desde allí y se almacena en caché/almacenado de tal manera que una consulta en una gran base de usuarios requeriría significativamente más memoria?

  2. En cada documento de usuario, almacena "seguidores" y "seguidores" para un acceso más rápido a cada uno. Obviamente, esto tiene la desventaja de los datos duplicados en el sentido de que existe una entrada para el usuario A que sigue al usuario B en ambos documentos del usuario en el campo respectivo, y su eliminación requiere una eliminación correspondiente en el otro. Técnicamente, esto podría estar considerando doblar el número de puntos de falla potencial para una eliminación simple. ¿Y MongoDB aún sufre de lo que he oído describir como "suizo en queso" de sus datos almacenados en la memoria cuando se producen eliminaciones, y por lo tanto, las eliminaciones de los 2 campos en lugar de 1 duplican el efecto de ese agujero en la memoria?

  3. Colección separada para almacenar seguidores de los usuarios, consultada de manera similar a los documentos del usuario en 1, excepto que obviamente los únicos datos a los que se accede son Seguidores, de modo que si los documentos del usuario contienen bastantes otros datos relevantes cada usuario, evitamos el acceso a esa información. Esto parece tener algo de una base de datos relacional y aunque sé que no siempre es un enfoque terrible solo por principio, obviamente si uno de los otros enfoques mencionados (o uno que no he considerado) es mejor bajo la arquitectura de Mongo ¡me encantaría aprender!

Si alguien tiene alguna idea sobre esto, o me quiere decir que he perdido una página muy relevante y documentos y evidente en alguna parte, o incluso me quiere decir que sólo estoy siendo estúpida (que se cree con una explicación de por qué, por favor;)) ¡Me encantaría saber de usted!

+0

¿Qué lenguaje de programación usará? Dependiendo de eso, hay ciertas características que el controlador subyacente puede o no admitir. En particular, estoy hablando de DBRefs. http://docs.mongodb.org/manual/applications/database-references/ –

+0

Ese es un buen punto, gracias. Podríamos terminar usando cualquier cosa, pero actualmente una mezcla de PHP y Node.js. – tdous

Respuesta

7

Este es un problema clásico seguidor-followee y no hay una sola respuesta a it..Check vistazo a este enlace:

mongo db design of following and feeds, where should I embed?

En realidad esta situación se presta muy bien a un esquema relacional, si MongoDB y SQL servidor fueron las únicas opciones que tuviste. Pero este es un tipo especial de problema relacional en el que tienes una relación bidireccional.Esto tal vez puede ser mejor manejado por una base de datos gráfica:

http://forum.kohanaframework.org/discussion/10130/followers-and-following-database-design-like-twitter/p1

La cosa es, usted podría o bien mantener seguidores o de aquellos que siguen en un documento del usuario, pero no ambos, para evitar problemas de doble eliminación. Así que si usted debe pegarse a MongoDB, una salida podría ser .. (suponiendo que las personas no siguen/unfollow cualquier persona que frecuencia),

Mantener sólo las de aquellos que siguen en el documento, ya que al ver el perfil, yo estaría interesado en la gente que sigo .. (esa es la razón por la que los seguía, en primer lugar, ¿verdad?) .. y luego hacer una consulta como:

db.Users.find({ user_id : { $in : followees })

Esto le dirá que todos están siguiendo yo (digamos que mi id es 'user_id').
Otra razón por la que no sugiero que sea al revés es que ... uno puede seguir como máximo 30-40 personas, por lo que el documento de usuario que almacena 30-40 seguidos debería estar bien, en comparación con un documento de usuario que almacena miles de seguidores! Con el enfoque follow-in-document, obtienes documentos del usuario de aproximadamente el mismo tamaño. En el enfoque del seguidor de documentos, tendrás algunos documentos muy pequeños pero también muy voluminosos. Y dependiendo de la cantidad de datos del seguidor que ingrese (si lo hay, aparte de follower_id), podría querer tener cuidado con el límite del tamaño del documento.

+1

¡Agradable! ¡Cubriste todos los puntos que tuve que decir! La opción 2 es definitivamente un no no. El camino a seguir es almacenar las identificaciones de los usuarios que está siguiendo. Obtener una lista de los usuarios que lo siguen es solo una consulta y puede indexarse. Consulte: http://www.mongodb.org/display/DOCS/Schema+Design –

+0

Esta es la forma en que también lo consideraría, sin embargo, estoy un poco preocupado por el problema de rendimiento de 'campo ilimitado' en mongo, que podría hacer de esto una mala elección. Ver: http://stackoverflow.com/questions/9306815/mongodb-performance-with-growing-data-structure ¿Cuáles son sus pensamientos sobre esto? – UpTheCreek

+0

@UpTheCreek El campo ilimitado aquí es la lista de gente que sigo. Suponiendo que esto no crezca más allá de 30-40 usuarios, sería un problema menor en comparación con tener un campo ilimitado que contiene miles de seguidores. Nuevamente, este argumento es muy específico para este caso de uso (follower-followee en estilo twitter). –

2

Dado que es una relación de muchos a muchos, la opción (2) se ve bien para mí. En cuanto a las eliminaciones coincidentes, generalmente no es un problema, siempre que tenga algún tipo de mecanismo de reconciliación entre los dos documentos.

La fragmentación generalmente depende de los patrones de acceso de la aplicación y generalmente es un problema con la mayoría de los sistemas de datos. Se han realizado algunos cambios significativos en mongo para evitar la fragmentación interna. Además, hay alternativas de compactación sin conexión para arreglar la fragmentación, si sucede.

Cuestiones relacionadas