¿Cuál es la forma más eficiente de almacenar mediciones con un número variable de campos en una base de datos?

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

  •  06-07-2019
  •  | 
  •  

Pregunta

Tenemos un sistema de recolección de datos que recolecta mediciones de sensores ambientales que miden la velocidad del agua que fluye a través de un río o canal. Cada medición genera un número fijo de valores (por ejemplo, Fecha, Hora, Temperatura, Presión, etc.) más una lista de valores de velocidad.
Originalmente, los sensores suministraban tres valores de velocidad, así que simplemente almacené cada valor en su propia columna de una sola tabla en una base de datos FireBird. Más tarde se introdujeron sensores que podían generar hasta nueve valores de velocidad, así que simplemente agregué seis columnas más. Aunque la mayoría de los sensores usan menos de 9 valores, calculé que no sería un problema si la mayoría de las columnas solo contuvieran ceros.
Pero ahora me enfrento a una nueva generación que puede generar desde 1 a 256 valores y supongo que no será muy eficiente agregar otras 247 columnas, especialmente porque la mayoría de las mediciones solo contendrán de 3 a 9 valores.
Dado que las mediciones se recopilan cada 10 minutos, y la base de datos contiene todos los datos de 30 a 50 sensores, la cantidad total de datos es bastante significativa después de unos años, sin embargo, debe ser posible generar vistas generales / gráficos para cualquier período de tiempo aleatorio.

Entonces, ¿cuál sería la forma más eficiente de almacenar la lista variable de valores?
Como cada registro tiene su propia ID única, supongo que podría almacenar todos los valores de velocidad en una tabla separada, cada valor etiquetado con su ID de registro. Simplemente tengo la sensación de que esto no sería muy eficiente y que se volvería muy lento después de un tiempo.

¿Fue útil?

Solución

Las bases de datos pueden manejar grandes cantidades de datos en una tabla si usa índices eficientes. Entonces puede usar esta estructura de tabla:

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

Cree un índice en id , id, seq y ts . Eso le permitirá buscar eficientemente a través de los datos. Si desconfía de su base de datos, simplemente inserte algunos millones de filas y ejecute un par de selecciones para ver qué tan bien le va.

Para comparación: tengo una base de datos Oracle aquí con 112 millones de filas y puedo seleccionar un registro por marca de tiempo o ID dentro de 120 ms (0.12s)

Otros consejos

Puede guardar datos serializados en un campo de texto, por ejemplo, codificando JSON las medidas como:

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

Luego, en su código, deserialice los valores después de consultar.

Esto debería funcionar bien si solo filtra sus consultas por los otros campos, y no por los valores guardados. Si filtra por los valores, usarlos en las cláusulas WHERE será una pesadilla.

Iría con una segunda tabla:

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

Velocity.MeasurementId hace referencia a Measurements.Id .
Velocity.Sequence es el índice del valor de velocidad para esa medición (1-256).

Rellene estas tablas con datos tan cercanos al mundo real como sea posible y pruebe las instrucciones sql para encontrar los mejores índices.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top