PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Django + Postgres + Grandes Séries Temporais


Se entendi corretamente, você está pensando em armazenar a série temporal no PostgreSQL, um registro de série temporal em uma linha do banco de dados. Não faça isso.

Por um lado, o problema é teórico. Os bancos de dados relacionais (e acho que a maioria dos bancos de dados) são baseados na premissa de independência de linha, enquanto os registros de uma série temporal são ordenados fisicamente. É claro que os índices de banco de dados fornecem alguma ordem para as tabelas de banco de dados, mas essa ordem destina-se a acelerar a pesquisa ou apresentar os resultados em ordem alfabética ou em alguma outra ordem; não implica nenhum significado natural para essa ordem. Independentemente de como você os encomenda, cada cliente é independente de outros clientes, e a compra de cada cliente é independente de suas outras compras, mesmo que você possa obtê-las totalmente cronologicamente para formar o histórico de compras do cliente. A interdependência dos registros de séries temporais é muito mais forte, o que torna os bancos de dados relacionais inadequados.

Na prática, isso significa que o espaço em disco ocupado pela tabela e seus índices será enorme (talvez 20 vezes maior do que armazenar as séries temporais em arquivos), e a leitura das séries temporais do banco de dados será muito lenta, algo como uma ordem de magnitude mais lento do que armazenar em arquivos. Também não lhe dará nenhum benefício importante. Você provavelmente nunca fará a consulta "me dê todos os registros de séries temporais cujo valor seja maior que X". Se você precisar de uma consulta desse tipo, também precisará de muitas outras análises que o banco de dados relacional não foi projetado para executar, então você lerá toda a série temporal em algum objeto de qualquer maneira.

Portanto, cada série temporal deve ser armazenada como um arquivo. Pode ser um arquivo no sistema de arquivos ou um blob no banco de dados. Apesar de eu ter implementado o último, acredito que o primeiro é melhor; no Django, eu escreveria algo assim:
class Timeseries(models.model):
    name = models.CharField(max_length=50)
    time_step = models.ForeignKey(...)
    other_metadata = models.Whatever(...)
    data = models.FileField(...)

Usando um FileField tornará seu banco de dados menor e tornará mais fácil fazer backups incrementais do seu sistema. Também será mais fácil obter fatias procurando no arquivo, algo que provavelmente é impossível ou difícil com um blob.

Agora, que tipo de arquivo? Eu aconselho você a dar uma olhada nos pandas. É uma biblioteca python para análise matemática que tem suporte para séries temporais, e também deve ter uma forma de armazenar séries temporais em arquivos.

Eu vinculei acima a uma biblioteca minha que eu não recomendo que você use; por um lado, não faz o que você deseja (não pode lidar com granularidade mais fina que um minuto e tem outras deficiências) e, por outro, está desatualizado - escrevi antes dos pandas e pretendo convertê-lo usar pandas no futuro. Há um livro, "Python for data analysis", do autor de pandas, que achei inestimável.

Atualização (2016): Há também o InfluxDB. Nunca usei e, portanto, não tenho opinião, mas definitivamente é algo que você precisa examinar se estiver se perguntando como armazenar séries temporais.

Atualização (2020-02-07): Há também o TimescaleDB, uma extensão do PostgreSQL.

Atualização (2020-08-07): Mudamos nosso software (novamente) para que ele armazene os dados no banco de dados usando TimescaleDB. Já somos versados ​​em PostgreSQL e foi fácil aprender um pouco de TimescaleDB. A vantagem concreta mais importante é que podemos fazer consultas como "encontrar todos os locais onde houve chuva>50mm em 24 horas em 2019", algo que seria muito difícil ao armazenar dados em arquivos planos. Outra vantagem são as verificações de integridade — ao longo dos anos tivemos algumas séries temporais com linhas duplicadas devido a pequenos bugs aqui e ali. As desvantagens também são significativas. Ele usa 10 vezes mais espaço em disco. Podemos precisar alterar nossa política de backup do PostgreSQL por causa disso. É mais lento. Demora talvez um segundo para recuperar uma série temporal com 300 mil registros. Isso foi instantâneo antes. Precisávamos implementar o cache para recuperar séries temporais, o que não era necessário antes.