2010-06-09 9 views
16

Là où je travaille, nous utilisons Ruby on Rails pour créer des applications backend et frontend. Habituellement, ces applications interagissent avec la même base de données MySQL. Cela fonctionne très bien pour la majorité de nos données, mais nous avons une situation dans laquelle j'aimerais passer à un environnement NoSQL.Lequel de CouchDB ou MongoDB correspond à mes besoins?

Nous avons des clients, et nos clients ont ce que nous appelons des «inventaires» - un ou plusieurs d'entre eux. Un inventaire peut contenir plusieurs milliers d'éléments. Ceci est actuellement effectué via deux tables de base de données relationnelles, inventories et inventory_items.

Les problèmes commencent lorsque deux inventaires différents ont différents paramètres:

# 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 
} 

Puisque nous ne pouvons évidemment pas utiliser brand ou star_rating comme nom de colonne dans inventory_items, notre solution a été jusqu'à présent d'utiliser des noms de colonnes génériques tels que text_a, text_b, float_a, int_a, etc, et d'introduire un troisième tableau, inventory_schemas. Les tableaux ressemblent maintenant à ceci:

# 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 
} 

Cela a bien fonctionné ... jusqu'à un certain point. C'est maladroit, c'est non intuitif et il manque d'évolutivité. Nous devons consacrer des ressources pour mettre en place des schémas d'inventaire. L'utilisation de tables séparées n'est pas une option.

Entrez NoSQL. Avec cela, nous pourrions laisser chaque élément avoir ses propres paramètres et les stocker encore ensemble. D'après les recherches que j'ai faites, cela semble certainement être une grande alternative à cette situation. En particulier, j'ai regardé CouchDB et MongoDB. Les deux sont super. Cependant, il y a quelques autres morceaux dont nous avons besoin pour être en mesure de le faire avec notre inventaire:

  • Nous devons être en mesure de sélectionner des éléments dans un seul (ou plusieurs) des stocks.
  • Nous devons être en mesure de filtrer les éléments en fonction de leurs paramètres (par exemple, obtenir tous les éléments de l'inventaire 2 où le type est 'hôtel').
  • Nous devons être en mesure de regrouper les articles en fonction des paramètres (par exemple, obtenir le prix le plus bas parmi les articles de l'inventaire 1 où la marque est «Samsung»).
  • Nous devons (potentiellement) être en mesure de récupérer des milliers d'éléments à la fois.
  • Nous devons pouvoir accéder aux données de plusieurs applications; à la fois backend (pour traiter les données) et frontend (pour afficher les données).
  • L'insertion en masse rapide est souhaitée, bien que non requise.

Basé sur la structure, et les exigences, sont CouchDB ou MongoDB appropriés pour nous? Si oui, lequel sera le meilleur?

Merci d'avoir lu, et merci d'avance pour les réponses.

EDIT: L'une des raisons pour lesquelles j'aime CouchDB est qu'il nous serait possible dans l'application frontend de demander des données via JavaScript directement depuis le serveur après chargement de la page, et d'afficher les résultats sans utiliser de code backend . Cela conduirait à une meilleure charge de la page et à une moindre sollicitation du serveur, car l'extraction/traitement des données se ferait côté client.

+0

Une autre chose que vous devez probablement considérer est l'intégrité des données dont vous avez besoin, c'est-à-dire avez-vous besoin d'un magasin de données conforme à l'acide. – nos

+0

Merci pour votre commentaire. En ce qui concerne l'intégrité, ce n'est pas une grande priorité. Nous importons un inventaire d'un seul coup, après quoi nous le manipulons rarement - seulement le voir. En tant que tel, je ne pense même pas que les transactions sont nécessaires. – vonconrad

Répondre

17

Je travaille sur MongoDB, donc vous devriez prendre ceci avec un grain de sel, mais cela ressemble à un excellent ajustement pour Mongo.

  • Nous devons être en mesure de sélectionner des éléments dans un seul (ou plusieurs) des stocks.

Il est facile d'effectuer des requêtes ad hoc sur tous les champs.

  • Nous devons être en mesure de filtrer les éléments en fonction de ses paramètres (par exemple. Obtenir tous les articles de l'inventaire 2 où le type est « hôtel »).

La requête pour ce serait: {"inventory_id" : 2, "type" : "hotel"}.

  • Nous devons être en mesure de regrouper les éléments en fonction des paramètres (par exemple. Obtenir le prix le plus bas articles en stock 1 où la marque est « Samsung »).

Encore une fois, super facile: db.items.find({"brand" : "Samsung"}).sort({"price" : 1})

  • Nous devons (potentiellement) être en mesure de récupérer des milliers d'objets à la fois.

Aucun problème.

  • insertion en vrac rapide est souhaitée, mais pas nécessaire.

MongoDB a inserts beaucoup plus rapide en vrac que CouchDB.

En outre, il y a une interface REST pour MongoDB: http://github.com/kchodorow/sleepy.mongoose

Vous pouvez lire http://chemeo.com/doc/technology, qui a traité le problème de la recherche de la propriété arbitraire avec MongoDB.

+0

Merci pour votre réponse! Une question de suivi: Sur le groupement, que se passe-t-il si je veux savoir quel est le prix le plus bas pour Samsung et Sony dans une requête? Et s'il y a 100 ou 1000 marques? En SQL, je peux utiliser 'SELECT MIN (prix) FROM table GROUP BY brand;' - est-ce quelque chose de similaire possible pour MongoDB? – vonconrad

+2

Oui, Mongo a une fonction de groupe qui équivaut à GROUP BY, voir http://www.mongodb.org/display/DOCS/Aggregation – kristina

Questions connexes