Qual è il modo più efficiente per memorizzare le misurazioni con un numero variabile di campi in un database?

StackOverflow https://stackoverflow.com/questions/1629458

  •  06-07-2019
  •  | 
  •  

Domanda

Abbiamo un sistema di raccolta dati che raccoglie misure da sensori ambientali che misurano la velocità dell'acqua che fluisce attraverso un fiume o un canale. Ogni misurazione genera un numero fisso di valori (ad es. Data, ora, temperatura, pressione ecc.) Più un elenco di valori di velocità.
Inizialmente i sensori fornivano tre valori di velocità, quindi ho semplicemente memorizzato ciascun valore nella sua colonna di una singola tabella in un database FireBird. Successivamente sono stati introdotti sensori in grado di produrre fino a nove valori di velocità, quindi ho semplicemente aggiunto altre sei colonne. Anche se la maggior parte dei sensori utilizza meno di 9 valori, ho calcolato che non sarebbe un problema se la maggior parte delle colonne contenesse solo zero.
Ma ora sto affrontando una nuova generazione che può produrre da 1 a 256 valori e presumo che non sarà molto efficiente aggiungere altre 247 colonne, soprattutto perché la maggior parte delle misurazioni conterrà solo da 3 a 9 valori. > Poiché le misurazioni vengono raccolte ogni 10 minuti e il database contiene tutti i dati per 30-50 sensori, la quantità totale di dati è abbastanza significativa dopo alcuni anni, tuttavia deve essere possibile generare panoramiche / grafici per qualsiasi periodo di tempo casuale.

Quindi quale sarebbe il modo più efficiente per memorizzare l'elenco delle variabili dei valori?
Poiché ogni record ha il suo ID univoco, suppongo che potrei semplicemente memorizzare tutti i valori di velocità in una tabella separata, ogni valore etichettato con il suo ID record. Ho solo la sensazione che questo non sarebbe molto efficiente e che dopo molto tempo diventerebbe molto lento.

È stato utile?

Soluzione

I database possono gestire grandi quantità di dati in una tabella se si utilizzano indici efficienti. Quindi puoi usare questa struttura di tabella:

create table measurements (
     id,
     seq integer, -- between 1 and 256
     ts timestamp, -- Timestamp of the measurement
     value decimal(...)
)

Crea un indice su id , id, seq e ts . Ciò ti consentirà di cercare in modo efficiente tra i dati. Se diffidi del tuo database, inserisci solo alcuni milioni di righe ed esegui un paio di selezioni per vedere come funziona.

Per un confronto: ho un database Oracle qui con 112 milioni di righe e posso selezionare un record per timestamp o ID entro 120ms (0.12s)

Altri suggerimenti

È possibile salvare dati serializzati in un campo di testo, ad esempio codifica JSON delle misure come:

[<velocity-value-1>, <velocity-value-2>, ...]

Quindi, nel tuo codice, deserializza i valori dopo l'interrogazione.

Questo dovrebbe funzionare bene se si filtrano le query solo dagli altri campi e non dai valori salvati. Se si filtrano i valori, usarli nelle clausole WHERE sarà un incubo.

Vorrei andare con un secondo tavolo:

table measurements (Id, DateTime, Temperature, Pressure)
table velocity (Id, MeasurementId, Sequence, Value)

Velocity.MeasurementId riferimenti Measurements.Id .
Velocity.Sequence è l'indice del valore di velocità per quella misurazione (1-256).

Popolare queste tabelle con i dati il ??più vicino possibile al mondo reale e prova le istruzioni sql per trovare gli indici migliori.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top