2010-06-09 6 views
16

Donde trabajo, utilizamos Ruby on Rails para crear aplicaciones tanto backend como frontend. Por lo general, estas aplicaciones interactúan con la misma base de datos MySQL. Funciona de maravilla para la mayoría de nuestros datos, pero tenemos una situación que me gustaría pasar a un entorno NoSQL.¿Cuál de los CouchDB o MongoDB se ajusta a mis necesidades?

Tenemos clientes, y nuestros clientes tienen lo que llamamos "inventarios" - uno o más de ellos. Un inventario puede tener muchos miles de artículos. Esto se realiza actualmente a través de dos tablas de bases de datos relacionales, inventories y inventory_items.

Los problemas comienzan cuando dos inventarios diferentes tienen diferentes parámetros:

# Inventory item from inventory 1, televisions 
{ 
    inventory_id: 1 
    sku: 12345 
    name: Samsung LCD 40 inches 
    model: 582903-4 
    brand: Samsung 
    screen_size: 40 
    type: LCD 
    price: 999.95 
} 

# Inventory item from inventory 2, accomodation 
{ 
    inventory_id: 2 
    sku: 48cab23fa 
    name: New York Hilton 
    accomodation_type: hotel 
    star_rating: 5 
    price_per_night: 395 
} 

Dado que obviamente no podemos utilizar brand o star_rating como el nombre de la columna en inventory_items, nuestra solución hasta el momento ha sido la utilización de nombres de columna genéricos como text_a, text_b, float_a, int_a, etc., e introduce una tercera tabla, inventory_schemas. Las tablas ahora se ven así:

# Inventory schema for inventory 1, televisions 
{ 
    inventory_id: 1 
    int_a: sku 
    text_a: name 
    text_b: model 
    text_c: brand 
    int_b: screen_size 
    text_d: type 
    float_a: price 
} 

# Inventory item from inventory 1, televisions 
{ 
    inventory_id: 1 
    int_a: 12345 
    text_a: Samsung LCD 40 inches 
    text_b: 582903-4 
    text_c: Samsung 
    int_a: 40 
    text_d: LCD 
    float_a: 999.95 
} 

Esto ha funcionado bien ... hasta cierto punto. Es torpe, no es intuitivo y carece de escalabilidad. Tenemos que dedicar recursos para configurar esquemas de inventario. Usar tablas separadas no es una opción.

Ingrese NoSQL. Con él, podríamos permitir que todos y cada uno de los artículos tengan sus propios parámetros y aun así almacenarlos juntos. De la investigación que he hecho, ciertamente parece una gran alternativa para esta situación.

Específicamente, he visto CouchDB y MongoDB. Ambos se ven geniales. Sin embargo, hay algunas otras partes que debemos poder hacer con nuestro inventario:

  • Necesitamos poder seleccionar elementos de solo uno (o varios) inventarios.
  • Necesitamos ser capaces de filtrar elementos en función de sus parámetros (por ejemplo, obtener todos los artículos del inventario 2, donde el tipo es 'hotel').
  • Tenemos que ser capaces de agrupar elementos según los parámetros (por ejemplo, obtener el precio más bajo de los artículos del inventario 1 donde la marca es 'Samsung').
  • Necesitamos (potencialmente) poder recuperar miles de elementos a la vez.
  • Necesitamos poder acceder a los datos de múltiples aplicaciones; tanto backend (para procesar datos) como frontend (para mostrar datos).
  • Se desea la inserción rápida a granel, aunque no es necesario.

Según la estructura y los requisitos, ¿son adecuados para nosotros CouchDB o MongoDB? Si es así, ¿cuál será la mejor opción?

Gracias por leer, y gracias de antemano por las respuestas.

EDITAR: Una de las razones por las que me gusta CouchDB es que nos sería posible en la aplicación de frontend solicitar datos vía JavaScript directamente desde el servidor después de la carga de la página, y mostrar los resultados sin tener que usar ningún código de back-end . Esto llevaría a una mejor carga de la página y menos tensión del servidor, ya que la obtención/procesamiento de los datos se realizaría desde el lado del cliente.

+0

Una cosa más que probablemente deba considerar es la integridad de datos que necesita, es decir, si necesita un almacén de datos compatible con el ácido. – nos

+0

Gracias por su comentario. Con respecto a la integridad, no es una gran prioridad. Importamos un inventario de una sola vez, después del cual raramente lo manipulamos, solo lo vemos. Como tal, ni siquiera creo que las transacciones sean necesarias. – vonconrad

Respuesta

17

Yo trabajo en MongoDB, por lo que debe tomar esto con un grano de sal, pero esto parece una excelente opción para Mongo.

  • Tenemos que ser capaces de seleccionar los artículos en sólo uno (o varios) inventarios.

Es fácil hacer consultas ad hoc en cualquier campo.

  • Tenemos que ser capaces de filtrar elementos en función de sus parámetros (por ejemplo. Obtener todos los artículos de inventario 2 donde tipo es 'hotel').

La consulta para esto sería: {"inventory_id" : 2, "type" : "hotel"}.

  • Tenemos que ser capaces de agrupar los elementos en base a parámetros (por ejemplo. Obtener el precio más bajo de artículos en inventario 1, donde la marca es 'Samsung').

Una vez más, muy fácil: db.items.find({"brand" : "Samsung"}).sort({"price" : 1})

  • Tenemos que (potencialmente) ser capaz de recuperar miles de artículos a la vez.

No hay problema. se desea

  • inserción mayor rápido, aunque no es necesario.

MongoDB tiene mucho más rápido que los insertos de mayor CouchDB.

Además, hay una interfaz REST para MongoDB: http://github.com/kchodorow/sleepy.mongoose

Es posible que desee leer http://chemeo.com/doc/technology, que trató con el problema de búsqueda del arbitrarias en MongoDB.

+0

Gracias por su respuesta! Una pregunta de seguimiento: en la agrupación, ¿qué ocurre si quiero saber cuál es el precio más bajo para Samsung y para Sony en una consulta? ¿Qué pasa si hay 100 o 1000 marcas? En SQL, puedo usar 'SELECT MIN (price) FROM table GROUP BY brand;' --¿es algo similar posible para MongoDB? – vonconrad

+2

Sí, Mongo tiene una función de grupo que es prácticamente equivalente a GROUP BY, consulte http://www.mongodb.org/display/DOCS/Aggregation – kristina

Cuestiones relacionadas