2010-09-28 16 views
21

Estoy construyendo un sistema de contabilidad simple donde un usuario tiene muchas facturas. Ahora estoy tratando de decidir si las facturas deben ser su propia colección o anidadas dentro del usuario. Me estoy inclinando por lo primero, pero NUNCA he hecho nada de SQL, así que voy por ensayo y error y lo que creo tiene sentido para mí.Mongo DB Design, incrustación vs relaciones

Entiendo que Mongo tiene un límite de tamaño de documento de 4mb, que es lo que me hace pensar que debería tener una colección separada para las facturas, ya que se acumularán diariamente y podrían ocupar una gran cantidad de espacio.

Estoy buscando opiniones al respecto. Básicamente voy a consultar las facturas de un usuario entre diferentes períodos de fechas (como se puede imaginar un sistema de contabilidad haría).

No es que realmente importe pero estoy usando Mongoid en un proyecto de Rails3. Pensé que haría algo como:

class User 
    references_many :bills 
end 

class Bill 
    referenced_in :user 
end 

Cualquier comentario o sugerencia de diseño es muy apreciada.

Respuesta

24

1) En cuanto al límite documento de 4 MB, esto es lo que el "MongoDB: The Definitive Guide" dice:

documentos de más de 4 MB (cuando se convierte a BSON) no se pueden guardar en la base de datos. Este es un límite algo arbitrario (y puede plantearse en el futuro); es sobre todo para evitar el mal diseño del esquema y garantizar un rendimiento constante. Para ver el tamaño BSON (en bytes) del documento doc, ejecute Object.bsonsize (doc) desde el shell.

Para darle una idea de cuánto 4MB es, el texto completo de War and Peace es sólo 3.14MB.

Al final, depende de qué tan grande espera que crezcan las facturas de un usuario. Espero que el extracto anterior te dé una idea de los límites impuestos por el tamaño del documento.

esquema

2) De-normalizada (facturas van con el documento de usuario) es el camino a seguir si usted sabe que nunca va a ejecutar consultas globales en las facturas (ejemplo de una consulta de este tipo se si desea recuperar el diez facturas más recientes ingresadas en el sistema). Tendrá que usar map-reduce para recuperar los resultados de tales consultas si usa un esquema desnormalizado.

El esquema normalizado (usuario y facturas en documentos separados) es una mejor opción si desea flexibilidad en la forma de consultar las facturas. Sin embargo, dado que MongoDB no admite combinaciones, deberá ejecutar múltiples consultas cada vez que desee recuperar las facturas correspondientes a un usuario.

Dado el caso de uso que mencionaste, iría con un esquema desnormalizado.

3) Todas las actualizaciones en MongoDB son atómicas y serializadas. Eso debería responder a la preocupación de Steve.

Puede encontrar estas diapositivas útiles. http://www.slideshare.net/kbanker/mongodb-meetup

También puede consultar la página Implementación de producción de MongoDB. Puede encontrar las diapositivas de SF.net útiles.

+0

ah solo está en la escritura ... ¿afecta esto a las opciones atómicas en los documentos integrados? Por ejemplo, si solo estoy haciendo un $ push en mis facturas en mi documento de usuario, ¿importa si mi usuario y todas sus facturas ascienden a 4mb, o solo si la factura en sí es 4mb en escritura? Tengo la sensación de que es lo último y, por lo tanto, estoy a salvo (ya que no hay forma posible de que una sola factura contenga 4mb de datos, o que estaría escribiendo suficientes facturas en 1 intento para alcanzar esa cantidad) ¿Suena bien? Asumiendo eso, creo que aceptaré su sugerencia y me iré desnormalizando. – brad

+0

Hmm ... Creo que estaba equivocado, estoy bastante seguro de que el límite de 4mb afectaría al usuario si sus cuentas excedieran esa cantidad, sin embargo, la cantidad de datos en una factura es bastante pequeña, así que lo voy a dar un tiro con billetes incrustados y hacer algunas pruebas en el futuro para ver qué tipo de capacidad de facturación puedo manejar – brad

1

Una pregunta que tal vez desee considerar es si alguna vez tendrá que hacer referencia individual a las facturas, aparte de su membresía en un usuario. Si es así, será más simple si tienen una existencia independiente.

Aparte de eso, el problema de límite de tamaño que ya ha identificado es una buena razón para dividirlos.

También puede haber un problema de transacción, si está escribiendo un usuario grande con muchas facturas incluidas, ¿qué sucede si obtiene escrituras razonablemente simultáneas de cambios en el mismo usuario desde diferentes conexiones? No sé lo suficiente sobre mongo para saber cómo resolvería esto; supongo que si las escrituras contuvieran diferentes facturas añadidas las obtendrías a ambas, pero si contuvieran cambios diferentes en las facturas existentes, recibirías sobrescrituras - Con suerte, alguien más comentará sobre esto, pero al menos lo probaría. Si está escribiendo las facturas en una colección separada, esto no es una preocupación.

1

pasado mucho tiempo desde que esta cuestión se ha abordado, pero que estaba tratando con algo similar y pensé que podría añadir mis hallazgos para cualquier otra persona a investigar este asunto.

Según tengo entendido, el documento de 4 MB se ha ampliado a 16 MB en las versiones 1.8+. Esto fue de una presentación en video de Banker, quien es uno de los miembros de MongoDB. NO he verificado este valor, pero estoy tomando su palabra (ya que con suerte él sabe de lo que está hablando).

En cuanto a la pregunta sobre qué sucede cuando se producen varias actualizaciones en el mismo usuario con facturas incrustadas ... otra vez desde la misma presentación de video, la respuesta es que MongoDB actualiza la información tan rápidamente que normalmente no es un problema. La instancia de MongoDB se bloquea mientras se realizan las actualizaciones, por lo que las actualizaciones múltiples no deberían ser un problema.

Una preocupación que tenía sobre los documentos incrustados es que no se pueden tratar independientemente de su documento original. Esto, en mi opinión, hace que los documentos incrustados sean inútiles. Solo son útiles para casos de nicho que cumplen casos de uso específicos.

personalmente he encontrado que MongoDB (y NoSQL DB) son útiles para casos particulares, sino que SQL tradicional/RDMSs todavía son mejores para la mayoría de los temas. Si usted es alguien como Craigslist y la alteración del esquema le lleva 2 meses ejecutar sus datos archivados, entonces sí, MongoDB y NoSQL tienen sentido. pero para la gran mayoría de las aplicaciones no creo que manejar esa cantidad de datos sea una gran preocupación.