MongoDB è la scelta giusta nel mio caso? [chiuso]

9

Costruirò il mio primo vero progetto in Rails che consiste in un'app web composta da 3 parti principali:

  • La parte statica in cui non viene utilizzato alcun database
  • La parte di registrazione utente che richiede un database e io posso usare MySQL poiché la riga di ogni utente avrà gli stessi campi
  • La "app" in cui gli utenti saranno in grado di creare, organizzare, modificare ... gli elementi nelle raccolte e condividerli con altri utenti

Ci saranno diversi tipi di articoli e ognuno avrà opzioni diverse, ad esempio potrei avere articoli "video" con le seguenti opzioni:

  • id
  • user_id
  • collection_id
  • titolo
  • piattaforma (se presente)
  • url (se incorporato)
  • nome del file (se ospitato sulla mia app)
  • dimensione del file (id ospitato sulla mia app)

e "mappa" elementi:

  • id
  • user_id
  • collection_id
  • titolo
  • piattaforma (google maps, bing maps ...)
  • posizione
  • url
  • dimensione della mappa

Come puoi mentre per gli utenti posso usare MySQL per gli articoli la flessibilità di MongoDB può essere utile dato che ogni articolo potrebbe necessitare di opzioni diverse da un altro elemento

Fino ad ora ho sempre usato PHP e MySQL (sempre su hosting condiviso per piccoli progetti) e la scalabilità è una parola totalmente nuova per me.

Ho tempo per imparare, ma mi piacerebbe essere in grado di fare qualcosa di concreto in qualcosa come 1 mese.

Ho letto molto su MongoDB e NoSQL rispetto a RDMS e MySQL e dopo averlo provato devo dire che mi piace come funziona MongoDB: niente tabelle, niente file e i suoi documenti come JSON:

  • Nella mia situazione cosa consiglieresti? perché?
  • A proposito di scalabilità potrebbero esserci problemi con MongoDB? se sì quando (in termini di dimensioni del DB) e questi problemi potrebbero rallentare considerevolmente la mia app?

Modifica: come funziona l'app

Dato che molti hanno chiesto questo è come vorrei che l'app funzionasse:

  1. Un utente si iscrive
  2. Ha effettuato l'accesso
  3. Crea la sua prima collezione iside che può creare oggetti infiniti
  4. Gli articoli sono di vario tipo e ogni tipo richiede dati diversi da salvare nel database e il tipo di elementi può essere aggiunto o modificato

Gli utenti possono creare altre collezioni e oggetti al suo interno.

Quindi abbiamo CRUD per le collezioni e gli elementi al loro interno e ogni raccolta / elemento è riferita a un utente specifico

Il problema principale di MySQL è che non ha uno schema flessibile, c'è un modo per risolverlo (una soluzione?)?

Pensando a NoSQL l'unico dubbio che ho riguarda il join, per esempio dato un certo tipo di raccolta voglio recuperare i dati relativi all'Utente con id = campo user_id nella collezione

EDIT: idea per continuare a utilizzare MySQL

Crea un campo nella tabella "items" con le impostazioni opzionali, ogni impostazione divisa da un | o un altro simbolo.

Quindi salverò da qualche parte una struttura di ogni elemento, le impostazioni opzionali, per esempio il tipo di elemento "note" necessita di due impostazioni opzionali "color" e "strange_setting", quando ottengo i dati da MySQL io dividerò il campo per facoltativo impostazioni in un array sapendo che il primo elemento nell'array è per "colore" e così via.

Che ne pensi? ci sono problemi con quella soluzione? hai altre idee?

    
posta Matteo Pagliazzi 10.03.2012 - 15:53
fonte

6 risposte

10

Potremmo non essere in grado di aiutarti finché non ci dici cosa intendi fare con l'app. I database relazionali fanno bene a certe cose, ei database NoSQL sono buoni per gli altri.

Come qualcuno mi ha detto una volta qui su SO:

the relational part of a relational DB is far more optimized than some other parts

Significa che puoi usare un database relazionale anche se sembra adattarsi ai tuoi casi d'uso. Non basta andare avanti con MongoDB per via della sua flessibilità / scalabilità. Questa è la prima riga su MongoDB su Wikipedia:

MongoDB (from "humongous") is an open source document-oriented NoSQL database system.

Hai davvero intenzione di utilizzare un DB orientato ai documenti? se nei tuoi casi d'uso c'è un po 'di grafica, allora puoi andare molto bene per un database grafico come Neo4j. Oppure puoi usare il meglio di SQL e NoSQL insieme come fanno alcune persone.

BTW, sto anche facendo un progetto in cui utilizzo le parti migliori di SQL e NoSQL.

Modifica Dico ancora una volta:

Guarda la sezione Neo4j vs Hadoop su questo articolo. Dice:

In principle, Hadoop and other Key-Value stores are mostly concerned with relatively flat data structures. That is, they are extremely fast and scalable regarding retrieval of simple objects, like values, documents or even objects.

Riferendosi allo stesso articolo, hai davvero bisogno di una struttura dati piatta per la quale stai andando per MongoDB? Questo alla fine dipende dai casi d'uso dettagliati, da come verranno eseguiti i passaggi 3 e 4.

Inoltre, potresti voler fare riferimento a queste domande:

link

link

( Controlla di sicuro la risposta in cima / selezionata della seconda domanda. Sei in questo dilemma che potrebbe risolverlo. )

Credo che queste domande abbiano tutte le informazioni che volevi sapere. Alla fine, sei tu che dovrai decidere se è MongoDb o qualcos'altro, possiamo solo raccomandare. Le uniche persone che conoscono i tuoi casi d'uso dettagliati sono te e il tuo team.

MODIFICA AGGIORNAMENTO (per la parte MySQL): Come ho capito, stai pianificando di archiviare qualcosa nel db e separarli attraverso un separatore. Questo presenta 2 problemi:

  1. Devi inoltre gestire qualsiasi input che avrà il separatore.
  2. La parte di archiviazione relazionale di un database relazionale è molto più ottimizzata rispetto alla parte di corrispondenza delle stringhe. Non andrei per uno schema in cui ho bisogno di fare la corrispondenza delle stringhe in un database per ottenere un risultato specifico. Ancora una volta sto sottolineando:

    the relational part of a relational DB is far more optimized than some other parts (e.g. string matching)

  3. Non utilizzare attributi multivalore. Le persone generalmente li temono.
risposta data 12.03.2012 - 07:05
fonte
8

Vedo molto questa domanda. Sembra sempre essere pensato come / o. MongoDB è un nuovo fantastico strumento. A volte sembra anche uno strumento brillante per tutto e questa può essere una scelta sbagliata nella mia esperienza.

Penso che la combinazione migliore sia SIA ENTRAMBI e vorrei elogiarvi per il vostro approccio all'uso di mylsql per alcune parti, come gli utenti, ma usare MongoDB per altre parti poiché ritengo che l'autenticazione e l'autorizzazione siano fatte meglio con mySQL e ci sono un sacco di esempi e moduli che lo fanno molto bene.

Per il pezzo "numero elevato di elementi", è qui che dovresti prendere in considerazione l'idea di utilizzare mongoDB se il tuo volume è alto, e / o si tratta principalmente di letture e / o di dati non strutturati.

Consiglierei di non basare la tua decisione sulla flessibilità di schema di Mongo. Gli schemi SQL e SQL sono nati dall'esigenza di disporre di dati strutturati e di essere in grado di eseguire calcoli e trasformazioni che sono possibili solo con una tale struttura. L'ho imparato da 5 anni di lavoro in un ruolo di data warehouse. Vorrei solo guardare a MongoBD per il problema delle prestazioni. Se siete o vi aspettate un volume elevato di utenti e richieste, diciamo 100.000 utenti e 20 richieste al secondo, userei mongoDB, altrimenti proverei a stare con sql. In molti casi utilizzerei mySQL per un volume basso, quindi, quando il volume, il reddito e l'infrastruttura lo supportano, passiamo ad Oracle, prima di mixare in mongoDB. Sono d'accordo sul fatto che non dovresti provare ad affrontare i problemi con il volume prima di sperimentarli, tuttavia se hai una buona idea di dove stai andando e non vuoi riscrivere le cose a metà strada lì ha molto senso scegliere le tecnologie giuste a breve. Ricorda che se hai davvero un volume così elevato ci sono tantissime opzioni e tecnologie a tutti i livelli dello stack che cercherai di utilizzare.

Ci sono aspetti negativi di dati strutturati in modo approssimativo. Io uso l'analogia del parcheggio qui. nessuna linea di demarcazione è ottima per le prime 3 vetture che entrano, ma man mano che entrano più macchine, un sacco di disorganizzazione inizia a succedere e cercare di parcheggiarsi o contare facilmente le auto e mantenere le corsie libere diventa un incubo. Organizzare ciò porta avanti il lavoro, segnando linee e divisori e flussi di traffico, ecc. Ma ripaga. A volte le cose cambiano naturalmente (le macchine diventano più grandi) e devi fare alcune modifiche - le linee di riverniciatura. Oltre al tempo di inattività standard per i rimborsi e la manutenzione annuali.

L'aspetto del design dello schema sarà probabilmente il più grande ostacolo per gli utenti tradizionali di mysql. Penso che la pagina MongoDb sulla progettazione dello schema sia d'aiuto. Il mio punto finale è che ogni tecnologia aggiunta nel mix aggiunge complessità. Ci sono spesso enormi difensori per ogni pezzo che dirà che "hai" di usarlo, ma ho scoperto che un fattore davvero grande è quanti pezzi ci sono. Implica più possibili punti di errore e soprattutto più di una base di conoscenza necessaria per chiunque altro debba sapere di lavorarci sopra.

fyi Rick Obsorne ha un incredibile schema di confronto è abbastanza unico!

    
risposta data 10.03.2012 - 17:40
fonte
2

Qui vedo molti argomenti validi per NoSQL vs MySQL. Un collegamento mancante riguarda la scala: se si vuole veramente scalare e si vuole farlo con un database interno, si avrà bisogno di MOLTA conoscenza dei database. Ci sono troppe storie dell'orrore là fuori dove le persone hanno fallito nel tentativo di implementare un sistema che si ridurrà all'infinito.

Se scegli davvero di seguire la rotta NoSQL (e sei pronto a prendere i costi che ne derivano - come nessun join), considera AWS DynamoDB (http://aws.amazon.com/dynamodb/). Qui puoi dimenticare l'intero database ridimensionandolo e concentrarti sulla tua applicazione. Buona fortuna.

Dichiarazione di non responsabilità: sono uno sviluppatore del team AWS DynamoDB, ma credo fermamente nel nostro prodotto. Provalo:)

    
risposta data 16.03.2012 - 22:00
fonte
1

Quindi, il tuo progetto può salvare nel tuo database due diversi tipi di oggetti:

  • Oggetto utente (che ha sempre i campi).
  • Oggetti app (che possono avere campi diversi). Un'app appartiene a un solo utente.

Una raccolta potrebbe essere creata o meno come un oggetto diverso, poiché è solo un tag per raggruppare app diverse. Per ragioni, diciamo che non ci sono raccolte e gli utenti hanno solo un elenco di applicazioni.

Mentre penso sia realizzabile su MySQL, in MongoDB avrai una maggiore flessibilità in termini di struttura degli oggetti app e probabilmente mapperà più naturalmente la tua rappresentazione nel database, rendendo il codice più semplice.

In MySQL avrai problemi a gestire diversi formati per diverse app, ma è possibile. Alcune idee:

  • Puoi creare una tabella intermedia con tutte le informazioni comuni tra tutti gli oggetti (id, id_utente, titolo, ecc.), quindi il tipo, così puoi cercarla su un'altra tabella con solo i campi non comuni per quella formato (ad es. file_name e file_size per i file). Dovrai creare una tabella diversa per ogni formato diverso. Se entrambe le tabelle sono indicizzate da app_id (chiave primaria), sarà abbastanza veloce, in quanto l'accesso a una tabella per un valore indicizzato è rapido.
  • È possibile codificare i dati in un formato e memorizzare standardizzati. Ad esempio, codifica i dati non comuni in JSON come stringa e memorizzali in un campo VARCHAR. Fai attenzione alle dimensioni di quel campo in modo da non esaurire lo spazio. Il formato può essere complesso (JSON) o semplice (solo valori separati da virgole)
  • Puoi creare diversi campi "generici", come int1, int2, str1, str2 e definire che str1 per un tipo di app è "nome_file" mentre per un tipo diverso potrebbe essere "posizione".

Su MongoDB, potrebbe essere semplice come usare solo due raccolte MongoDB, una per gli utenti e un'altra per le app. Supponendo una sorta di limite (che non è il caso, come hai descritto, ma solo per averlo detto), potresti persino memorizzare le app all'interno dell'oggetto utente, come una lista. Memorizzare e recuperare i dati è più naturale, in quanto è possibile memorizzare qualsiasi tipo di oggetto, indipendentemente dai campi. Puoi cercare per user_id per ottenere tutte le app che appartengono a un utente. Su MongoDB perdi comunque la possibilità di fare query di join, ma in questo caso penso che le query di base saranno recuperare l'utente e recuperare le app relative all'utente. Se hai intenzione di fare un sacco di cose come "dammi gli utenti che hanno più di due collezioni con tre applicazioni o meno su ciascuna", dovrai generarlo non come una query di join, ma come un processo nel codice, e sarà meno naturale rispetto a un database relazionale e può richiedere più tempo per l'elaborazione. Se vuoi cercare i parametri (es. Dammi tutte le app che appartengono ad un particolare utente, dammi tutte le app che sono di tipo X), questo è abbastanza facile su MongoDB e non è necessario utilizzare i join.

Non sono sicuro del supporto di MongoDB su Rails. Lo uso in Python e JavaScript.

EDIT: aggiunto commento sul tempo quando si accede a due tabelle e un'altra opzione MySQL

    
risposta data 13.03.2012 - 14:59
fonte
1

Direi di usare la tecnologia che conosci meglio, specialmente se si tratta di un vero progetto e vuoi espellerlo velocemente. L'uso di MySQL e Mongo porterà entrambi i suoi vantaggi e i suoi grattacapi. Avendo lavorato con entrambi, vorrei anche aggiungere che non è molto difficile migrare da MySQL a Mongo se si seguono principi di progettazione validi.

Detto questo, un buon motivo per andare con MongoDB nel tuo caso sono i tuoi dati. Come hai menzionato, avrai diversi tipi di inserimento per le tue collezioni: mappa, video e così via. Se dovessi implementarlo usando RDBMS, hai 3 approcci:

  • tabella per tipo: ogni tabella contiene colonne specifiche per ogni tipo di oggetti

    Svantaggi : N query per la ricerca in tutti i tipi di dati.

    Vantaggi : buona progettazione OO, facile da mantenere

  • tabella singola: una tabella enorme contenente tutti i possibili attributi per tutti i tipi, con la maggior parte di essi null per ogni particolare voce

    Svantaggi : la modifica di qualsiasi oggetto richiede un'alterazione della tabella, dolorosa quando la tabella diventa grande. Difficile da mantenere.

    Vantaggi : facile da implementare.

  • tabella principale con meta-dati: hai una singola tabella con il nucleo attributi, ad esempio titolo, date e una tabella di metadati con valore-chiave coppie per attributi aggiuntivi

    Svantaggi : due query per ottenere tutti i dati per un singolo oggetto.

    Vantaggi : estremamente flessibile, non molto difficile da implementare.

Ho già usato ciascuno di questi approcci, e posso dire che nessuno è altrettanto naturale con Mongo. I tuoi dati saranno probabilmente simili a questo:

{_id:"collection1",
 name:"My first Collection",
 owner: "user123243342",
 entries: [
    {type:"video",
     url: "http://www.youtube.com/234324",
     tags: ["roadtrip", "fun", "camera"]
     },
    {type:"map",
     coordinates: [LOC: [38, –102], LOC: [43, –33], LOC: [228, –102]],
     description: "Road trip to nowhere",
 ]
}

Ma non dovrai preoccuparti del design dello schema, dato che i tuoi oggetti di dominio possono essere mantenuti direttamente come tali. MongoDB è essenzialmente il tuo negozio di oggetti su cui puoi eseguire una query.

Notato Non ho lasciato alcuna discussione sul confronto delle prestazioni tra MySql e Mongodb. Mentre si deve sempre tenere a mente le prestazioni, non si sarà in grado di prendere decisioni efficaci a meno che non si conosca il modello di accesso ai dati. Ogni buon progetto probabilmente passerà attraverso alcune iterazioni del refactoring man mano che crescerà e emergeranno nuove sfide. Non preoccuparti delle prestazioni prestabilite e scegli lo strumento che conosci meglio e inizia a programmare.

Modifica

Per rispondere alla tua domanda specifica sull'uso di MySQL e mantenere gli attributi nello stesso campo usando "|". Non farlo. Questo approccio ti darà più problemi di quanti ne risolva. Prima di tutto, non sarai in grado di interrogare i singoli attributi usando MySql. In secondo luogo aggiunge troppa complessità al livello di accesso ai dati. Utilizzare invece l'approccio tipo-tabella o meta-dati. Se hai già lavorato con WordPress, utilizza l'approccio meta-dati:

  • tabella utente + usemeta per utente
  • post tabella + post tabella postmeta

Ciò rende la struttura dei dati estremamente flessibile e ancora in grado di interrogare con una velocità ragionevole.

    
risposta data 14.03.2012 - 03:52
fonte
0

L'articolo seguente fornisce buoni risultati nel confronto tra MySQL e MongoDB in termini di selezione, recupero e inserimento, considerando la quantità di dati nel database e la quantità di dati recuperati. I risultati mostrano una grande perfomance per MongoDB per quanto riguarda gli "inserti", ma gli altri casi che MySQL vince. Vedi sotto:

link

Ho avuto un'esperienza con MongoDB che penso sia stata una buona soluzione. L'ho usato per inserire migliaia di collezioni ogni giorno. Combinato con la soluzione Solr (soluzione cache, aggiornata una volta al giorno), posso recuperare i dati MongoDB dall'ID della raccolta quando necessario, quindi non ho bisogno di selezionare al volo. Quindi, considerando che devi gestire molti inserti e non devi preoccuparti di selezionare e recuperare, MongoDB potrebbe essere una grande idea, dipenderà da ciascun caso e farà una buona analisi.

    
risposta data 16.02.2014 - 03:25
fonte

Leggi altre domande sui tag