2010-06-09 4 views
16

Dove lavoro, usiamo Ruby on Rails per creare sia applicazioni backend che frontend. Di solito queste applicazioni interagiscono con lo stesso database MySQL. Funziona alla grande per la maggior parte dei nostri dati, ma abbiamo una situazione che vorrei passare ad un ambiente NoSQL.Quale di CouchDB o MongoDB si adatta alle mie esigenze?

Abbiamo clienti ei nostri clienti hanno ciò che chiamiamo "inventari" - uno o più di essi. Un inventario può contenere molte migliaia di articoli. Questo viene attualmente eseguito attraverso due tabelle di database relazionali, inventories e inventory_items.

I problemi iniziano quando due inventari differenti hanno differenti parametri:

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

Dal momento che, ovviamente, non possiamo usare brand o star_rating come il nome della colonna in inventory_items, la nostra soluzione finora è stata quella di utilizzare i nomi delle colonne generici ad esempio text_a, text_b, float_a, int_a, ecc. e introdurre una terza tabella, inventory_schemas. Le tabelle ora appaiono così:

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

Questo ha funzionato bene ... fino ad un certo punto. È goffo, non intuitivo e privo di scalabilità. Dobbiamo dedicare risorse per impostare schemi di inventario. L'utilizzo di tabelle separate non è un'opzione.

Immettere NoSQL. Con esso, potremmo lasciare ogni singolo elemento avere i propri parametri e ancora memorizzarli insieme. Dalla ricerca che ho fatto, sembra certamente un grande alterativo per questa situazione.

In particolare, ho esaminato CouchDB e MongoDB. Entrambi sembrano grandi. Tuttavia, ci sono alcuni altri elementi che dobbiamo essere in grado di fare con il nostro inventario:

  • Dobbiamo essere in grado di selezionare gli articoli da uno (o più) inventari.
  • Dobbiamo essere in grado di filtrare gli elementi in base ai relativi parametri (ad esempio, ottenere tutti gli articoli dall'inventario 2 in cui il tipo è 'hotel').
  • Dobbiamo essere in grado di raggruppare gli articoli in base ai parametri (ad esempio ottenere il prezzo più basso dagli articoli nell'inventario 1 in cui il marchio è "Samsung").
  • Dobbiamo (potenzialmente) essere in grado di recuperare migliaia di elementi alla volta.
  • Abbiamo bisogno di essere in grado di accedere ai dati da più applicazioni; entrambi back-end (per elaborare i dati) e frontend (per visualizzare i dati).
  • L'inserimento rapido e voluminoso è desiderato, sebbene non richiesto.

In base alla struttura e ai requisiti, CouchDB o MongoDB sono adatti a noi? Se sì, quale sarà la migliore soluzione?

Grazie per la lettura, e grazie in anticipo per le risposte.

EDIT: Uno dei motivi per cui CouchDB mi piace è che sarebbe possibile per noi nell'applicazione frontend richiedere i dati tramite JavaScript direttamente dal server dopo il caricamento della pagina e visualizzare i risultati senza dover utilizzare alcun codice di backend di sorta . Ciò porterebbe a un migliore caricamento della pagina ea una minore sollecitazione del server, poiché l'acquisizione/elaborazione dei dati verrebbe eseguita sul lato client.

+0

Un'altra cosa che probabilmente dovresti prendere in considerazione è la quantità di integrità dei dati di cui hai bisogno: ad esempio, hai bisogno di un datastore conforme agli acidi. – nos

+0

Grazie per il tuo commento. Per quanto riguarda l'integrità, non è una priorità enorme. Importiamo un inventario in un unico colpo, dopo il quale raramente lo manipoliamo - lo vediamo solo. In quanto tale, non penso nemmeno che le transazioni siano necessarie. – vonconrad

risposta

17

Io lavoro su MongoDB, quindi dovresti prendere questo con un pizzico di sale, ma questo sembra un ottimo adattamento per Mongo.

  • abbiamo bisogno di essere in grado di selezionare gli elementi da solo uno (o più) delle scorte.

È facile eseguire query ad hoc su qualsiasi campo.

  • abbiamo bisogno di essere in grado di filtrare gli elementi in base ai suoi parametri (ad es. Ottenere i lotti di inventario 2 dove tipo è 'struttura').

La query per questo sarebbe: {"inventory_id" : 2, "type" : "hotel"}.

  • abbiamo bisogno di essere in grado di raggruppare gli elementi in base a parametri (ad es. Ottenere il prezzo più basso da oggetti in inventario 1 in cui brand è 'Samsung').

Anche in questo caso, super facile: db.items.find({"brand" : "Samsung"}).sort({"price" : 1})

  • Abbiamo bisogno di (potenzialmente) in grado di recuperare le migliaia di oggetti alla volta.

Nessun problema.

  • inserimento bulk Rapid è desiderato, anche se non richiesto.

MongoDB ha inserti molto più veloce di massa di CouchDB.

Inoltre, c'è un'interfaccia REST per MongoDB: http://github.com/kchodorow/sleepy.mongoose

Si potrebbe desiderare di leggere http://chemeo.com/doc/technology, che ha affrontato il problema arbitraria di ricerca immobili, con MongoDB.

+0

Grazie per la tua risposta! Una domanda di follow-up: sul raggruppamento, cosa succede se voglio scoprire qual è il prezzo più basso per Samsung e Sony in una query? Cosa succede se ci sono 100 o 1000 marchi? In SQL posso usare 'SELECT MIN (prezzo) FROM tabella GROUP BY marca;' --è qualcosa di simile possibile per MongoDB? – vonconrad

+2

Sì, Mongo ha una funzione di gruppo che è praticamente equivalente a GROUP BY, vedi http://www.mongodb.org/display/DOCS/Aggregation – kristina