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 dell'utente che richiederà un database e posso usare MySQL poiché ogni riga dell'utente avrà gli stessi campi
  • L '"App" in cui gli utenti saranno in grado di creare, organizzare, modificare ... elementi nelle raccolte e condividerli con altri utenti

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

  • id
  • ID utente
  • collection_id
  • titolo
  • piattaforma (se integrata)
  • url (se incorporato)
  • nome file (se ospitato sulla mia app)
  • dimensione del file (ID ospitato sulla mia app)

e "mappa" elementi:

  • id
  • ID utente
  • 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 poiché ogni articolo potrebbe aver bisogno di opzioni diverse rispetto a un altro oggetto

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 vorrei essere in grado di fare qualcosa di concreto in qualcosa come 1 mese.

Ho letto molto su MongoDB e NoSQL vs RDMS e MySQL e dopo averlo provato devo dire che mi piace il modo in cui MongoDB funziona: niente tabelle, niente righe e i suoi documenti come JSON in questo modo:

  • 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 possono rallentare notevolmente la mia app?

Modifica: come funzionerà l'app

Poiché 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 infiniti oggetti
  4. Gli articoli sono di vario tipo e ogni tipo necessita di dati diversi per essere salvato nel database e il tipo di elementi può essere aggiunto o modificato

Gli utenti possono creare altre raccolte ed elementi al suo interno.

Quindi abbiamo CRUD per le raccolte e gli oggetti al loro interno e ogni raccolta / oggetto è riferito a un utente specifico

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

Pensando a NoSQL, l'unico dubbio che ho riguarda il join, ad esempio, data una certa raccolta, voglio recuperare i dati relativi all'utente con il campo id = user_id nella raccolta

EDIT: Idea per continuare a utilizzare MySQL

Creare un campo nella tabella "articoli" con impostazioni opzionali, ciascuna impostazione divisa per un | o un altro simbolo.

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

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


4
Le domande di Matteo sulle raccomandazioni tecnologiche sono fuori tema, a meno che tu non ci presenti un problema specifico che stai cercando di risolvere. Dovrai fornirci un po 'più di informazioni sul tuo progetto e sul perché pensi di dover utilizzare qualsiasi altro database diverso da MySQL (che è quello che conosci). Ad esempio: vi sono problemi di scalabilità e quanto tempo è necessario esaminare le nuove tecnologie. Prendi in considerazione la possibilità di rivedere la tua domanda e, in caso affermativo, contrassegnala per l'attenzione di moderazione in modo che possiamo rivedere le tue modifiche.
yannis,

Risposte:


10

Potremmo non essere in grado di aiutarti finché non ci comunichi cosa intendi fare con l'app. I database relazionali sono buoni per alcune cose e i database NoSQL sono buoni per altre.

Come qualcuno una volta mi ha detto qui su SO:

la parte relazionale di un DB relazionale è molto più ottimizzata di alcune altre parti

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

MongoDB (da "humongous") è un sistema di database NoSQL orientato ai documenti open source.

Intendi davvero utilizzare un DB orientato ai documenti? Se c'è un po 'di grafosità nei tuoi casi d'uso, allora potresti benissimo cercare un database grafico come Neo4j. Oppure puoi benissimo usare insieme il meglio di SQL e NoSQL come fanno alcune persone.

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

EDIT: dico ancora una volta:

Dai un'occhiata alla sezione Neo4j vs Hadoop su questo articolo. Dice:

In linea di principio, Hadoop e altri negozi Key-Value si occupano principalmente di strutture di dati relativamente piatte . Cioè, sono estremamente veloci e scalabili per quanto riguarda il recupero di oggetti semplici, come valori, documenti o persino oggetti.

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

Inoltre, potresti voler fare riferimento a queste domande:

/programming/2124274/mongodb-what-to-know-before-using

/programming/1476295/when-to-use-mongodb-or-other-document-oriented-database-systems

( Controlla la risposta superiore / selezionata della seconda domanda di sicuro. Sei in quel dilemma che questo potrebbe risolvere. )

Immagino 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 sei tu e il tuo team.

MODIFICA ANCORA (per la parte MySQL): come ho capito, stai pensando di archiviare qualcosa nel db e separarli attraverso un separatore. Ciò presenta 2 problemi:

  1. È necessario gestire ulteriormente 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 vorrei optare per uno schema in cui è necessario eseguire la corrispondenza delle stringhe in un database per ottenere risultati specifici. Ancora una volta sottolineo:

    la parte relazionale di un DB relazionale è molto più ottimizzata di alcune altre parti (ad es. corrispondenza delle stringhe)

  3. Non utilizzare attributi multivalore. La gente generalmente li teme.

principalmente stavo per usare MongoDB per il suo schema flessibile ma ho dei dubbi poiché non ha aderito. Comunque nella mia app avrò un dtabase per gli utenti e poi una base di base in cui ogni elemento è associato a un utente e una raccolta di elementi
Matteo Pagliazzi

Non avrai bisogno di unirti a mongo ma dovrai pianificare il tuo schema. Pensa in termini di oggetti anziché di tabelle se usi mongo. Quindi pensa a come accederai ai tuoi oggetti.
ltfishie,

8

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

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

Per il pezzo "gran numero di elementi", è qui che dovresti prendere in considerazione l'uso di mongoDB se il tuo volume è alto e / o è principalmente letto e / o sono dati non strutturati.

Consiglierei di non basare la tua decisione sulla flessibilità senza schema di Mongo. Gli schemi SQL e sql sono nati dalla necessità di disporre di dati strutturati e di essere in grado di eseguire calcoli e trasformazioni possibili solo con una struttura del genere. L'ho imparato da 5 anni di lavoro nel ruolo di data warehouse. Vorrei solo guardare MongoBD per il problema delle prestazioni. Se stai aspettando un volume elevato di utenti e richieste, diciamo 100.000 utenti e 20 richieste al secondo, userei mongoDB, altrimenti proverei a rimanere con sql. In molti casi userei mySQL per un volume basso e poi, dato che volume, reddito e infrastruttura lo supportano, passerei a Oracle, prima di mescolarlo in mongoDB. Sono d'accordo che non dovresti provare a gestire i problemi di volume prima di sperimentarli, tuttavia se hai una buona idea di dove stai andando e non " Non voglio riscrivere le cose a metà strada, ha molto senso scegliere le tecnologie giuste fin dall'inizio. Ricorda solo che se hai un volume così elevato, ci sono moltissime opzioni e tecnologie a tutti i livelli dello stack che cercherai di usare.

Ci sono svantaggi di dati vagamente strutturati. Uso l'analogia del parcheggio qui. nessuna linea di demarcazione è ottima per le prime 3 macchine che entrano, ma man mano che entrano più macchine, iniziano a verificarsi molti disorganizzanti e cercare di parcheggiare o contare facilmente le macchine e mantenere le corsie libere diventa un incubo. Organizzare questo richiede un lavoro iniziale: tracciare linee, divisori e flussi di traffico, ecc., Ma paga. A volte le cose cambiano ovviamente (le macchine diventano più grandi) e devi fare alcuni cambiamenti: ridipingere le linee. Inoltre solo i tempi di fermo standard per le riduzioni e la manutenzione annuali.

L'aspetto della progettazione dello schema sarà probabilmente il più grande ostacolo per gli utenti mysql tradizionali. Penso che la pagina MongoDb sulla progettazione dello schema sia di aiuto in questo. Il mio ultimo punto è che ogni tecnologia che aggiungi al mix aggiunge complessità. Ci sono spesso grandi sostenitori di ogni dato pezzo che diranno che "devi" usarlo, ma ho scoperto che un fattore veramente grande è proprio quanti pezzi ci sono. Implica più possibili punti di fallimento e soprattutto una base di conoscenza necessaria affinché chiunque altro debba sapere di lavorarci.

Rick Rick Obsorne ha un diagramma di confronto piuttosto sorprendente che è abbastanza unico!


questo è il mio primo vero progetto in rotaie: è un hobby e per ora non so se sarà un successo o un fallimento il mio primo obiettivo qui è quello di conoscere le rotaie, quindi non posso parlare di traffico. Le letture non saranno primarie, avrò anche molti nuovi dati e uno aggiornato ...
Matteo Pagliazzi

1
una cosa bella di mongodb è che non esiste uno schema fisso, quindi per un progetto hobby c'è meno lavoro di installazione. Lo schema può evolversi nel tempo e non è necessario eseguire il passaggio aggiuntivo di aggiornamento delle tabelle SQL.
Kevin

non sei sicuro del mio -1 o perché 0 cattivi consigli o disaccordo?
Michael Durrant,

Ad ogni modo, se questo è il tuo primo progetto su rotaie, rimarrei con mySQL. C'è molto da imparare su binari, molto più di 1 mese dopo aver iniziato a tirare indietro le tende.
Michael Durrant,

@michael guarda il mio ultimo aggiornamento
Matteo Pagliazzi il

3

Vedo molti argomenti validi qui per NoSQL vs MySQL. Un collegamento mancante riguarda la scalabilità: se vuoi davvero ridimensionare e vuoi farlo con un database interno, avrai bisogno di MOLTE conoscenze sui database. Ci sono troppe storie dell'orrore là fuori in cui le persone hanno fallito nel tentativo di implementare un sistema che si ridimensionerà all'infinito.

Se scegli davvero di seguire il percorso NoSQL (e sei pronto a sostenere i costi che ne derivano - come nessun join), considera AWS DynamoDB (http://aws.amazon.com/dynamodb/). Qui puoi dimenticare tutto il database ridimensionandolo e concentrarti sulla tua applicazione. In bocca al lupo.

Disclaimer: sono uno sviluppatore del team AWS DynamoDB, ma credo fermamente nel nostro prodotto. Provalo :)


1

Quindi, il tuo design arriva a 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 o meno farmi diventare un oggetto diverso, in quanto è solo un tag per raggruppare diverse app. Per ragioni di argomento, supponiamo che non ci siano raccolte e che gli utenti abbiano 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 formati diversi per app diverse, ma è possibile. Qualche idea:

  • Puoi creare una tabella intermedia con tutte le informazioni comuni tra tutti gli oggetti (id, id_utente, titolo, ecc.), Quindi il tipo, quindi puoi cercarla su un'altra tabella con solo i campi non comuni per quel formato (ad es. nome_file e dimensione_file per i file). Dovrai creare una tabella diversa per ciascun formato diverso. Se entrambe le tabelle sono indicizzate da app_id (chiave primaria), sarà abbastanza veloce, poiché l'accesso a una tabella con un valore indicizzato è veloce.
  • È possibile codificare i dati in un formato e archiviarli standardizzati. Ad esempio, codificare i dati non comuni in JSON come stringa e archiviarli in un campo VARCHAR. Fai attenzione alle dimensioni di quel campo in modo da non rimanere a corto di spazio. Il formato può essere complesso (JSON) o semplice (solo valori separati da virgole)
  • Puoi creare diversi campi "generici", qualcosa 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 dire), potresti persino archiviare le app all'interno dell'oggetto utente, come un elenco. La memorizzazione e il recupero dei dati è più naturale, poiché è 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 il recupero dell'utente e il recupero delle app correlate all'utente. Se hai intenzione di fare un sacco di cose come "dammi gli utenti che hanno più di due raccolte con tre applicazioni o meno su ciascuna", dovrai generarlo non come 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 parametri (ad es. Dammi tutte le app che appartengono a un determinato utente; dammi tutte le app di tipo X), è abbastanza facile su MongoDB e non è necessario utilizzare i join.

Non sono sicuro del supporto di MongoDB su Rails. L'ho usato in Python e JavaScript.

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


non mi piace la seconda opzione per usare MySQL per memorizzare le impostazioni opzionali perché penso che possa caricare ogni riga con molti byte non necessari ... per la seconda: rallenterà molto la mia app per caricare due file da due diverse tabelle per caricare un articolo?
Matteo Pagliazzi,

per favore, vedi il mio ultimo aggiornamento
Matteo Pagliazzi,

A proposito della tua domanda sulla velocità, non dovrebbe essere molto più lento (stai accedendo tramite un valore univoco indicizzato). Ho anche modificato la mia risposta, poiché l'ultima proposta modificata è simile alla prima idea e ho aggiunto un'altra opzione.
Khelben

1

Direi di usare la tecnologia che conosci meglio, soprattutto se si tratta di un vero progetto e vuoi spingerlo fuori velocemente. L'uso di MySQL e Mongo comporta entrambi vantaggi e mal di testa. Avendo lavorato con entrambi, aggiungerei anche che non è molto difficile migrare da MySQL a Mongo se segui i principi del buon design.

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

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

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

    Vantaggi : buon design OO, facile da mantenere

  • tabella singola: una tabella enorme che contiene tutti gli attributi possibili per tutti i tipi, con la maggior parte di essi nulli per qualsiasi voce particolare

    Svantaggi : la modifica a qualsiasi oggetto richiederà una modifica della tabella, dolorosa una volta che la tabella diventa grande. Difficile da mantenere.

    Vantaggi : facile da implementare.

  • tabella principale con metadati: hai una singola tabella con gli attributi principali, ad esempio titolo, date e una tabella dei metadati con coppie chiave-valore per attributi aggiuntivi

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

    Vantaggi : estremamente flessibile, non molto difficile da implementare.

Ho usato ciascuno di questi approcci in precedenza e posso dire che nessuno lavora in modo naturale con Mongo. I tuoi dati probabilmente avranno un aspetto simile al seguente:

{_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 davvero preoccuparti della progettazione dello schema, poiché i tuoi oggetti di dominio possono essere direttamente persistenti come tali. MongoDB è essenzialmente il tuo archivio oggetti su cui puoi interrogare.

Ho notato che ho lasciato fuori qualsiasi discussione sul confronto delle prestazioni tra MySql e Mongodb. Mentre dovresti sempre tenere a mente le prestazioni, non sarai in grado di prendere decisioni efficaci se non conosci il modello di accesso ai dati. Ogni buon progetto probabilmente passerà attraverso alcune iterazioni di refactoring man mano che cresce e emergono nuove sfide. Non preoccuparti delle prestazioni in anticipo e scegli lo strumento che conosci meglio e inizia a scrivere codice.

modificare

Per rispondere alla tua domanda specifica sull'uso di MySQL e sul mantenimento degli 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 eseguire query su singoli attributi utilizzando MySql. In secondo luogo aggiunge troppa complessità al livello di accesso ai dati. Utilizzare invece l'approccio tipo per tabella o metadati. Se hai lavorato con WordPress in precedenza, utilizza l'approccio dei metadati:

  • tabella utente + usemeta per l'utente
  • post table + post postmeta

Ciò rende la struttura dei dati estremamente flessibile e comunque in grado di eseguire query con una velocità ragionevole.


non mi piace l'opzione dei metadati ... ma sto pensando alla singola tabella con i campi lasciati nulli se non utilizzati
Matteo Pagliazzi

L'approccio a tavolo singolo è probabilmente il peggiore del gruppo. Sebbene sia possibile eseguire tutte le operazioni in una singola query, qualsiasi modifica a qualsiasi singolo tipo di dati richiederà la modifica della tabella. Ed è un dolore in mysql quando il tuo tavolo diventa grande.
ltfishie,

0

L'articolo seguente fornisce buoni risultati confrontando 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 grandi prestazioni per MongoDB per quanto riguarda gli "inserti", ma gli altri casi vincono MySQL. Vedi sotto:

http://www.moredevs.ro/mysql-vs-mongodb-performance-benchmark/

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.