Utilizzo di un database relazionale e non relazionale nello stesso progetto?

3

Mi sono imbattuto in un problema sul progetto al quale sto lavorando in questo momento. È fondamentalmente un'app che memorizza un percorso basato su coordinate GPS. L'app funziona su Android e salva la posizione GPS ogni secondo e poi la invia all'API. Penso che se inserisco un record per ogni posizione salvata ci saranno molti record nella tabella molto velocemente. Per esempio se vado di corsa tre volte alla settimana per 1 ora ci saranno 10'800 nuovi record a settimana, ora immagina questo con 1000 utenti attivi per un anno ...

Ad ogni modo, ho un'idea, che non ho mai visto prima e non sono sicuro che sia buona:

Uso un database relazionale (MySql) per memorizzare gli utenti (e tutti gli altri dati si aspettano dai percorsi registrati) e poi ho una tabella users_paths che collega gli utenti ai loro percorsi registrati (ovviamente), il percorso stesso è memorizzato in un database noSql (MongoDB) in un documento come questo:

_id:3474348347389,
waypoints:{
  {lat, long},
  {lat, long},
  ...
} 

Non l'ho ancora implementato perché mi sembra sbagliato e un po 'eccessivo per me. Ho anche pensato di salvare i percorsi registrati come file JSON ma non sono contento nemmeno con quella soluzione.

Che ne pensi? Questa è "la strada da percorrere" o ho completamente torto?

    
posta Jonas Wirth 25.02.2017 - 11:10
fonte

4 risposte

7

For example if I go on a run three times a week for 1 hour there will be 10'800 new records per week, now imagine this with 1000 active users for a year.

Bene, non proviamo imagine , ma in realtà stimiamo la crescita dei dati. Immaginate che ogni coordinata GPS sia memorizzata in due variabili a 32 bit (in gran parte sufficienti, probabilmente non è necessario avere molta precisione.) Tre ore a settimana significa 10.800 record o 675 KB di memoria. Per un migliaio di utenti, otteniamo 659,18 MB di aumento dei dati a settimana, o 2,6 GB al mese o 33,57 GB all'anno.

Pertanto, occorrerà sessant'anni per riempire un disco rigido di una capacità di 2 TB.

Tornando alla domanda iniziale, con un insieme di dati così piccolo, la scelta tra RDBMS e database non relazionali non ha importanza. Scegli quello che ti è familiare.

    
risposta data 25.02.2017 - 11:31
fonte
3

Per il tuo caso d'uso specifico, non utilizzerei due database diversi. Basta salvare i percorsi dei tuoi utenti come una geometria nel tuo RDBMS (sia esso MySQL o Postgres). I moderni database relazionali supportano i tipi di dati geospaziali e consentono un accesso constrongvole. In questo modo puoi eseguire le analisi geospaziali (come durata della corsa, velocità, incroci con altri utenti, ...) nel tuo database.

Provare a creare il proprio tipo di dati di geometria personalizzato (cioè definire una sorta di schema di documento in mongodb) sarà un classico esempio di "reinventare la ruota". Tutti i principali motori di database sono in grado di archiviare, interrogare e manipolare le geometrie e i dati geografici.

Dai un'occhiata a PostGIS o Spatial Extensions per MySQL se si desidera utilizzare i database Open Source. Sia Oracle che MSSQL supportano anche i dati spaziali.

In questo modo potrai utilizzare i tuoi dati con strumenti standard come esporli a WMS, WFS o qualsiasi altro tipo di rendering spaziale.

    
risposta data 26.02.2017 - 13:52
fonte
1

L'unico modo per saperlo è implementare entrambi e misurare durante un test di caricamento.

Ma intuitivamente, penso che armeggiare con due diversi database non può essere una buona idea, perché nessuno dei DBMS può fare un'ottimizzazione globale sugli accessi ai dati correlati. Questo è eccessivo e non migliorerà così tanto le prestazioni.

O metti tutti i tuoi dati in mongoDB o tutti i tuoi dati in rdbms. Il tuo modello MongoDB va bene. Per rdbms, è possibile utilizzare una tabella waypoint. I numeri che citi non sono un problema per il recupero. Gli Rdbms sono progettati per elaborare in massa tali dati.

Se nello scenario rdbms non è necessario l'accesso al database per singoli punti del percorso, è possibile scegliere di memorizzare il percorso completo come singolo blob (archiviazione binaria del flusso di coordinate GPS), che eviterà il interpretare questo lotto di dati ad ogni riga di recupero. Il blob sarebbe quindi una scatola nera per i rdbms. Verrebbe gestito dalla tua app per rendere graficamente il percorso o calcolare attributi come la distanza e la velocità o la velocità del segmento.

Si noti che se si intende accedere in db query a singoli punti del percorso (ad esempio per vedere se due corridori utilizzano percorsi simili o potrebbero incrociarsi tra loro), quindi, in base alla risoluzione e alla precisione del GPS, il punto singolo potrebbe non essere sufficiente comunque. Dovresti quindi utilizzare meglio un motore di database che supporta query e indici geospaziali (ad es. MongoDB o Aerospike )

    
risposta data 25.02.2017 - 11:31
fonte
-2

Mentre le altre risposte hanno mostrato che la quantità di dati non è così grande da riempire un disco da 2TB, dovresti considerare anche le velocità di accesso a quei dati. Se si utilizzano i tradizionali dischi rigidi del computer e non gli SSD, possono eseguire solo circa 100 accessi casuali al secondo (forse un po 'meno per i dischi desktop da 7200 RPM e un po' di più per i dischi aziendali da 10000-15000 RPM).

I database relazionali tipici memorizzano le informazioni su un file flat, il che significa che se ci sono 1000 utenti attivi, si avrà la seguente struttura: user0data0 user1data0 user2data0 ... user999data0 user0data1 user1data1 user2data1 ... user999data1 ... che significa che il recupero molti punti dati appartenenti a un utente significano un accesso casuale per punto dati.

Ora, se l'intero set di dati non si adatta alla memoria (i server tipici hanno una memoria da 32-64 GB e si riempirà tale quantità in 1-2 anni), se si desidera ad es. per ottenere i punti dati dell'ultimo giorno per un utente casuale, sono necessari 86 400 accessi casuali, ovvero 864 secondi o più di 14 minuti. Hai la possibilità di attendere 14 minuti per i dati dell'ultimo giorno? Probabilmente no.

Che cosa succede se si memorizzano i punti dati di un dato utente all'interno di un singolo documento come un file? Le informazioni dei file vengono generalmente archiviate consecutivamente su disco (anche se alcuni sistemi di file più recenti come ZFS e btrfs interrompono questa ipotesi, ma assumiamo che si stia utilizzando il file system tradizionale come ext2, ext3 o ext4). Ora per recuperare 86400 punti di dati, richiede una ricerca del disco casuale e una scansione sequenziale di 86400 punti di dati. A 8 byte per punto di dati, è di 0,66 megabyte che richiedono circa 7 millisecondi per leggere (supponendo che si leggano solo i punti di interesse dei dati e non l'intero documento). Questo aggiunto alla ricerca di 10 millisecondi è di 17 millisecondi. Se leggi l'intero documento per un anno, è la scansione sequenziale di 2,6 secondi e la ricerca casuale di 10 millisecondi, il che potrebbe essere un problema.

Quindi, prenderei in considerazione la possibilità di suddividere i documenti in parti più piccole: un documento al giorno per utente.

Quindi, come sommario, i database SQL non sono la tecnologia da utilizzare per archiviare i dati sulla posizione. La tua idea è buona, ma potrebbe richiedere un miglioramento (suddividendo il file di grandi dimensioni in piccoli pezzi al giorno).

Qualunque cosa tu faccia, si prega di implementare test per popolare il database con i dati, nello stesso ordine in cui i dati arriverebbero in un sistema reale. Quindi esegui query casuali sui dati, ad es. per ottenere il percorso di un utente casuale in un giorno casuale e misurare le prestazioni di tali query.

Modifica: potrebbero esserci alcune tecnologie dipendenti dal database che potrebbero consentire di ridurre il sovraccarico degli accessi casuali. Ad esempio, le versioni recenti di PostgreSQL supportano solo le scansioni dell'indice. Ciò significa che se si crea un indice che contiene tutte le colonne a cui si accede nella query, la query sarà soddisfatta solo dall'indice. MySQL InnoDB supporta indici clusterizzati, in cui i dati vengono memorizzati nell'indice anziché in un file flat. Tuttavia, utilizzando queste tecnologie, le prestazioni del tuo programma dipendono dai dettagli di implementazione interna del database. Lo vuoi? Se si è certi che non si passerà a un altro database che non dispone di queste funzionalità, è possibile ottenere con queste funzionalità prestazioni accettabili. Tuttavia, se vuoi rendere indipendente la tua base di dati del programma, memorizzare altrove i dati sulla posizione è una buona idea.

    
risposta data 25.02.2017 - 13:02
fonte