Timeseries: SQL o NoSQL?


33

Non mi interessano le differenze generali tra SQL e NoSQL (o le loro differenze tradizionali).

Attualmente sto cercando di modificare l'archiviazione delle nostre serie storiche interne. Tutti contengono dati finanziari provenienti da diverse fonti. Attualmente, stiamo memorizzando i nostri dati in un database proprietario. È molto NoSQL, che ha il suo linguaggio di query.

Sono interessato all'input della community: come memorizzeresti i dati in un database SQL? Quali sono i meriti per l'utilizzo di SQL su un NoSQL, in particolare per le serie storiche? Sono pazzo per aver considerato di archiviarlo in SQL?

Il nostro set di dati è costituito da milioni di serie temporali, con circa il 10% di queste contenenti milioni di record ciascuna. Le serie temporali sono organizzate gerarchicamente: / Mercato / Strumento / Valore / Frequenza, dove:

  • Il mercato è uno scambio di valori mobiliari, ecc., Fondamentalmente una raccolta di strumenti, di solito strumenti simili.
  • Lo strumento è uno strumento. Questo potrebbe essere un indicatore (Brent Crude), un'equità (GOOG), ecc
  • Il valore è uno dei molteplici tipi di dati per uno strumento. Questo potrebbe essere vicino, alto, basso, ecc
  • La frequenza è la frequenza di determinati valori di serie temporali. Settimanale, giornaliera, mensile, tick, arbitraria, ecc.

Come verrebbero archiviati i dati in un db SQL? Un grande tavolo (forse partizionato da qualcosa), un tavolo per mercato o strumento, un tavolo per serie storica.

Grazie in anticipo.


1
Tutte le serie temporali contengono gli stessi metadati (ovvero colonne)?
Jack Douglas,

1
Sembra un data warehouse ... Vedi questo su SO: stackoverflow.com/q/2684462/27535
gbn

@ jack-douglas: lo stai chiedendo di suggerire un archivio dati orientato alle colonne?
Nicolas

3
@Nicolas Non mi aspetto che un RDBMS SQL tradizionale sia adatto ai tuoi dati perché a) sarebbe più facile interrogare, b) i volumi non sembrano impraticabilmente grandi (miliardi di righe?) C) il partizionamento della data sembra naturale e / o funzionalità OLAP standard. Stavo chiedendo dei metadati per determinare quante tabelle sono necessarie. Se ogni serie temporale ha metadati unici, hai bisogno di milioni di tabelle che non sembrano una buona idea su un normale RDBMS, ma non penso che tu ne abbia bisogno, vero?
Jack Douglas,

2
@Nicolas hai esaminato il nuovo connettore Hadoop per SQL Server . In superficie, il tuo scenario sembra adattarsi.
Mark Storey-Smith,

Risposte:


26

In generale, per un set di dati così strutturato ho il sospetto che tu possa scrivere un formato di dati personalizzato che è stato più veloce per la maggior parte delle operazioni quotidiane (ad es. Estrazioni di piccoli dati da un tempo arbitrario). Il vantaggio di passare a uno strumento DB standard è probabilmente in alcuni extra, ad esempio query ad hoc, accesso multiplo, replica, disponibilità ecc. È anche più semplice assumere un aiuto per mantenere un archivio di dati basato su standard.

Se mi chiedessero di impostare un database per archiviare quei dati, farei quanto segue:

Schema proposto

(1) I dati di base sono inseriti in numerose (1000) di singole tabelle, ciascuna contenente due colonne:

  1. time: un tipo di dati DATETIME SQL o un tipo numerico di qualche epoca (questa è la chiave primaria)
  2. valore: digitato come appropriato per i tuoi dati. Per impostazione predefinita, utilizzare il float a precisione singola, tuttavia un tipo di dati a virgola fissa potrebbe essere più appropriato per le transazioni finanziarie. Questo probabilmente non è indicizzato.

Queste tabelle diventeranno piuttosto grandi e potresti volerle partizionare manualmente per (ad esempio) anno. Ma dovrai controllare le prestazioni del sistema e ottimizzare come appropriato.

Queste tabelle hanno bisogno di nomi univoci e ci sono un paio di opzioni. Potrebbero essere leggibili dall'uomo (ad es. Nyse_goog_dailyhighs_2010) o (le mie preferenze) casuali. In entrambi i casi è necessario un set di tabelle di metadati e nomi di tabelle casuali impediscono agli sviluppatori di dedurre qualcosa nel nome che non si intendeva dedurre.

(2) I metadati sono memorizzati in tabelle separate, come richiesto dall'applicazione :

Per tenere traccia dei metadati è necessaria una tabella o un set di tabelle aggiuntivi. Queste tabelle conterranno dati su scambio, strumento, valore, frequenza, intervalli di date, provenienza (da dove provengono i dati) e qualsiasi altra cosa di cui tu abbia bisogno. Questi sono associati ai nomi delle tabelle di dati.

Se ci sono abbastanza dati, questa ricerca potrebbe effettivamente fornire un nome di tabella e un nome di database, consentendo una sorta di sharding dei dati auto-implementato (se questo è l'uso corretto del termine). Ma lo terrei in riserva.

Quindi a livello di applicazione interrogherei le tabelle dei metadati per determinare dove si trovavano i miei dati e quindi eseguire query relativamente semplici sulle tabelle dei big data per ottenere i miei dati.

vantaggi:

  • La mia esperienza (relativamente limitata) è che i database possono generalmente gestire un gran numero di piccole tabelle più facilmente di un numero minore di grandi tabelle. Questo approccio consente anche una manutenzione più semplice (ad es. Eliminazione di vecchi dati, ricostruzione di una tabella corrotta, creazione / ricarica da backup, aggiunta di una nuova entità). Ciò disaccoppia completamente i diversi tipi di dati, se (ad esempio) si hanno dati a velocità diverse o se si richiedono tipi di dati diversi.

  • Questo concetto di tabella scarna dovrebbe anche consentire un accesso rapido al disco per quello che sospetto sia la query più comune, un intervallo contiguo di dati da una singola entità. La maggior parte delle applicazioni di dati ha un I / O su disco limitato, quindi vale la pena considerare. Come ha già suggerito un commentatore, questa è la mia applicazione ideale per un database orientato alle colonne, ma devo ancora trovare un prodotto orientato alle colonne che sia abbastanza mainstream per poter scommettere sulla mia carriera. Questo schema si avvicina molto.

svantaggi:

  • Circa metà dello spazio su disco è dedicata alla memorizzazione di timestamp, quando francamente 100 o 1000 delle tabelle avranno gli stessi dati esatti nella colonna timestamp. (In realtà questo è un requisito se si desidera eseguire semplici join di tabelle).

  • La memorizzazione dei nomi delle tabelle e l'esecuzione della ricerca dinamica richiedono molta complessità dell'applicazione e operazioni sulle stringhe, il che mi fa rabbrividire. Ma sembra ancora meglio delle alternative (discusso di seguito).

considerazioni:

  • Fai attenzione agli arrotondamenti nel tuo campo temporale. Vuoi che i tuoi valori siano abbastanza rotondi da consentire i join (se appropriato), ma abbastanza precisi da non essere ambigui.

  • Fare attenzione ai fusi orari e all'ora legale. Questi sono difficili da testare. Applicerei un requisito UTC sull'archivio dati (che potrebbe rendermi impopolare) e gestire le conversioni nell'applicazione.

variazioni:

Alcune variazioni che ho considerato sono:

Piegatura dei dati: se la serie temporale è equidistante, utilizzare una colonna timestamp e (ad esempio) 10 colonne di dati. Il timestamp ora si riferisce al tempo della prima colonna di dati e le altre colonne di dati sono assunte equamente distanziate tra quel timestamp e quello successivo. Ciò consente di risparmiare molto spazio di archiviazione precedentemente utilizzato per archiviare i timestamp, a un costo di complessità significativa delle query e / o delle applicazioni. Intervallo contiguo, le query a singola entità ora richiedono meno accesso al disco.

Multiplexing: se è noto che più serie temporali utilizzano le stesse serie temporali, utilizzare un timestamp e (ad esempio) 10 colonne di dati come descritto sopra. Ma ora ogni colonna rappresenta una serie temporale diversa. Ciò richiede un aggiornamento della tabella dei metadati, che non è una ricerca nel nome della tabella e della colonna. Lo spazio di archiviazione è ridotto. Le query rimangono semplici. Tuttavia, per un intervallo contiguo, le query a singola entità richiedono ora un accesso al disco significativamente maggiore.

Mega-table: porta il concetto di "multiplazione" all'estremo e metti tutti i dati in una singola tabella, una volta serie temporali per colonna. Ciò richiede grandi quantità di accesso al disco per intervalli contigui, query di singole entità ed è un incubo per la manutenzione. Ad esempio, l'aggiunta di una nuova entità ora richiede un comando MODIFY TABLE su una tabella con molti TB.

Per ulteriori discussioni su questo formato, vedere le varie risposte in: Troppe colonne in MySQL

Tabella completamente normalizzata: anziché utilizzare molte tabelle a 2 colonne, è possibile utilizzare una tabella a tre colonne, in cui le colonne sono time, dataid e value. Ora le tue tabelle di metadati devono solo cercare valori ID, anziché tablenames o nomi di colonne, il che consente di inserire più logica nelle query SQL, piuttosto che nel livello dell'applicazione.

Circa i 2/3 dello spazio di archiviazione vengono ora consumati con le colonne di normalizzazione, quindi questo utilizzerà molto spazio su disco.

È possibile utilizzare un ordine di chiave principale di (dataid, timestamp) per query rapide contigue, singole entità. In alternativa, è possibile utilizzare un ordine di chiave principale di (timestamp. Dataid) per inserimenti più rapidi.

Tuttavia, anche dopo aver considerato queste variazioni, il mio piano per il mio prossimo sviluppo è costituito da molte tabelle, ciascuna a due colonne. Quello o il metodo che presto verrà pubblicato da qualcuno più saggio di me :).


Grazie mille per la tua risposta. Hai sollevato alcuni punti molto validi. Sono completamente d'accordo con la memorizzazione in UTC. Sto rafforzando l'idea che tutti i dati vengano consegnati ai frontend (web, desktop e mobile) in UTC. Abbiamo clienti multinazionali e il sistema operativo dovrebbe essere responsabile per la conversione temporale. Ho una società DBA che lavora su tutto il nostro set di dati e mi chiedevo cosa avrebbero escogitato gli altri. Grazie ancora.
Nicolas,

Mentre i consulenti DBA lavorano per indirizzare un'installazione robusta di SQL Server, andrò avanti con i test con un'installazione BigData.
Nicolas,

Potrebbe essere una buona soluzione, ma la vera applicazione "serie storiche" dovrebbe supportare la funzionalità di "zoom in data" e il database non può essere d'aiuto. I database delle serie temporali riguardano più lo "zoom in" intelligente e il "zoom out".
Roman Pokrovskij,

1

Usa MongoDB, puoi creare raccolte al volo molto rapidamente. Cerca di organizzare i tuoi dati in database separati e raccolte all'interno di tali database. Considera la quantità di memoria necessaria per cercare di mantenere ogni frammento nella memoria di sistema, se hai bisogno di un recupero rapido. Stupido attenersi a una soluzione interna, se c'è qualcosa di più fresco là fuori che si evolverà lungo le linee di cui hai bisogno. Sembra una buona iniziativa.


2
Come memorizzeresti le serie storiche in Mongo? Ogni documento è una serie temporale? o il valore di un timestamp specifico?
RockScience

Per fare ciò in modo efficiente per dati non periodici o anche periodici, è meglio pre-allocare blocchi di dati. Ogni blocco sarebbe un documento con una piccola quantità di dati contabili, una matrice di dimensioni fisse per i tuoi valori e una matrice di dimensioni fisse per i tuoi tempi. Conserveresti quindi i tuoi metadati per le serie in un documento separato. In questo documento di metadati, conservare un piccolo documento nidificato che fungerà da contabile per i segmenti di dati, ad esempio tenere traccia dell'indice di array corrente e del segmento _id.
RYS,
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.