sql >> Base de Datos >  >> RDS >> PostgreSQL

Django + Postgres + Grandes series de tiempo

Si entiendo sus pensamientos correctamente, está considerando almacenar la serie temporal en PostgreSQL, un registro de serie temporal en una fila de la base de datos. No hagas eso.

Por un lado, el problema es teórico. Las bases de datos relacionales (y creo que la mayoría de las bases de datos) se basan en la premisa de la independencia de las filas, mientras que los registros de una serie temporal están ordenados físicamente. Por supuesto, los índices de las bases de datos proporcionan algún orden para las tablas de las bases de datos, pero ese orden está destinado a acelerar la búsqueda oa presentar los resultados alfabéticamente o en algún otro orden; no implica ningún significado natural para ese orden. Independientemente de cómo los ordene, cada cliente es independiente de otros clientes, y la compra de cada cliente es independiente de sus otras compras, incluso si puede obtenerlas todas juntas cronológicamente para formar el historial de compras del cliente. La interdependencia de los registros de series temporales es mucho más fuerte, lo que hace que las bases de datos relacionales sean inapropiadas.

En la práctica, esto significa que el espacio en disco ocupado por la tabla y sus índices será enorme (quizás 20 veces mayor que el almacenamiento de series temporales en archivos), y la lectura de series temporales de la base de datos será muy lenta, algo así como una orden. de magnitud más lento que el almacenamiento en archivos. Tampoco te dará ningún beneficio importante. Probablemente nunca haga la consulta "Dame todos los registros de series temporales cuyo valor sea mayor que X". Si alguna vez necesita una consulta de este tipo, también necesitará muchos otros análisis para los que la base de datos relacional no ha sido diseñada, por lo que leerá la serie temporal completa en algún objeto de todos modos.

Por lo tanto, cada serie temporal debe almacenarse como un archivo. Puede ser un archivo en el sistema de archivos o un blob en la base de datos. A pesar de que he implementado este último, creo que el primero es mejor; en Django, escribiría algo como esto:

class Timeseries(models.model):
    name = models.CharField(max_length=50)
    time_step = models.ForeignKey(...)
    other_metadata = models.Whatever(...)
    data = models.FileField(...)

Usando un FileField hará que su base de datos sea más pequeña y facilitará la realización de copias de seguridad incrementales de su sistema. También será más fácil obtener cortes buscando en el archivo, algo que probablemente sea imposible o difícil con un blob.

Ahora, ¿qué tipo de archivo? Te aconsejo que eches un vistazo a los pandas. Es una biblioteca de python para análisis matemático que admite series temporales y también debería tener una forma de almacenar series temporales en archivos.

Enlacé arriba a una biblioteca mía que no recomiendo usar; por un lado, no hace lo que quieres (no puede manejar una granularidad más fina que un minuto y tiene otras deficiencias) y, por otro lado, está desactualizado:lo escribí antes de pandas y tengo la intención de convertirlo usar pandas en el futuro. Hay un libro, "Python para el análisis de datos", del autor de pandas, que me ha parecido invaluable.

Actualización (2016): También está InfluxDB. Nunca lo usé y, por lo tanto, no tengo opinión, pero definitivamente es algo que debe examinar si se pregunta cómo almacenar series temporales.

Actualización (2020-02-07): También está TimescaleDB, una extensión de PostgreSQL.

Actualización (2020-08-07): Cambiamos nuestro software (nuevamente) para que almacene los datos en la base de datos usando TimescaleDB. Ya estamos versados ​​en PostgreSQL y fue fácil aprender algo de TimescaleDB. La ventaja concreta más importante es que podemos realizar consultas como "encontrar todos los lugares donde hubo lluvia>50 mm en 24 horas en 2019", algo que sería muy difícil al almacenar datos en archivos planos. Otra ventaja son las verificaciones de integridad:a lo largo de los años, tuvimos algunas series temporales con filas duplicadas debido a pequeños errores aquí y allá. Los inconvenientes también son significativos. Utiliza 10 veces más espacio en disco. Es posible que tengamos que cambiar nuestra política de copia de seguridad de PostgreSQL debido a eso. es mas lento Se tarda quizás un segundo en recuperar una serie temporal con 300k registros. Esto fue un instante antes. Necesitábamos implementar el almacenamiento en caché para recuperar series temporales, que antes no era necesario.