Séries temporais: SQL ou NoSQL?

33

Eu não ligo para as diferenças gerais entre SQL e NoSQL (ou suas diferenças tradicionais).

Atualmente, estou olhando para alterar o armazenamento de nossas séries temporais internas. Todos eles contêm dados financeiros de várias fontes diferentes. Atualmente, estamos armazenando nossos dados em um banco de dados proprietário. É muito o NoSQL, que possui sua própria linguagem de consulta.

Estou interessado na entrada da comunidade: como você armazenaria os dados em um banco de dados SQL? Que méritos existem para usar SQL em um NoSQL, especificamente para séries temporais? Estou louco por considerar armazenar isso no SQL?

Nosso conjunto de dados consiste em milhões de séries temporais, com cerca de 10% delas contendo milhões de registros cada. As séries temporais são organizadas hierarquicamente: / Mercado / Instrumento / Valor / Frequência, em que:

  • O mercado é uma bolsa de valores, etc, basicamente uma coleção de instrumentos, geralmente instrumentos semelhantes.
  • Instrumento é um instrumento. Pode ser um indicador (Brent Crude), um patrimônio (GOOG), etc.
  • O valor é um dos vários tipos de dados para um instrumento. Pode ser perto, alto, baixo, etc.
  • Frequência é a frequência de determinados valores de séries temporais. Semanal, diário, mensal, tick, arbitrário etc.

Como os dados seriam armazenados em um banco de dados SQL? Uma mesa grande (talvez particionada por algo), uma mesa por mercado ou instrumento, uma mesa por série temporal.

Agradeço antecipadamente.

Nicolas
fonte
11
Todas as séries temporais contêm os mesmos metadados (ou seja, colunas)?
Jack Douglas
11
Soa como um data warehouse ... Veja isso no SO: stackoverflow.com/q/2684462/27535
gbn
@ jack-douglas: Você está pedindo para sugerir um armazenamento de dados orientado a colunas?
Nicolas
3
@Nicolas Não, minha expectativa é que um SQL RDBMS tradicional seja adequado para seus dados, porque a) seria mais fácil consultar, b) os volumes não soariam impraticávelmente grandes (bilhões de linhas?) C) o particionamento de datas parece natural e / ou recursos OLAP padrão. Eu estava perguntando sobre os metadados para determinar quantas tabelas você precisa. Se cada série temporal possui metadados exclusivos, você precisa de milhões de tabelas, o que não parece uma boa ideia em um RDBMS comum, mas acho que você não precisa, não é?
Jack Douglas
2
@ Nicolas, você consultou o novo conector do Hadoop para SQL Server . Na superfície, seu cenário parece se encaixar.
Mark Storey-Smith

Respostas:

26

Em geral, para um conjunto de dados estruturado, suspeito que você possa escrever um formato de dados personalizado mais rápido para a maioria das operações diárias (ou seja, pequenos dados extraídos de um momento arbitrário). O benefício de mudar para uma ferramenta de banco de dados padrão é provável em alguns extras, como consultas ad hoc, acesso múltiplo, replicação, disponibilidade etc. Também é mais fácil contratar ajuda para manter um armazenamento de dados baseado em padrões.

Se me pedissem para configurar um banco de dados para armazenar esses dados, faria o seguinte:

Esquema proposto

(1) Os dados principais são colocados em várias (1000's) de tabelas individuais, cada uma contendo duas colunas:

  1. time: um tipo de dados SQL DATETIME ou um tipo numérico de alguma época (esta é a chave primária)
  2. valor: digitado conforme apropriado para seus dados. Eu teria como padrão a flutuação de precisão única, no entanto, um tipo de dados de ponto fixo pode ser mais apropriado para transações financeiras. Provavelmente isso não é indexado.

Essas tabelas ficarão muito grandes e você poderá particioná-las manualmente por (por exemplo) ano. Mas você terá que verificar o desempenho do sistema e ajustar conforme apropriado.

Essas tabelas precisam de nomes exclusivos e existem algumas opções. Eles podem ser legíveis por humanos (por exemplo, nyse_goog_dailyhighs_2010) ou (minha preferência) aleatórios. De qualquer maneira, é necessário um conjunto de tabelas de metadados, e os nomes aleatórios das tabelas impedem que os desenvolvedores deduzam algo no nome que não deveria ser deduzido.

(2) Os metadados são armazenados em tabelas separadas, conforme exigido pelo aplicativo :

Uma tabela ou conjunto de tabelas adicional é necessária para acompanhar os metadados. Essas tabelas conterão dados sobre trocas, instrumento, valor, frequência, intervalos de datas, procedência (de onde vieram os dados), além de qualquer outra coisa que você precise. Eles são mapeados para nomes de tabelas de dados.

Se houver dados suficientes, essa pesquisa poderá fornecer um nome de tabela e um banco de dados, permitindo um tipo de compartilhamento de dados auto-implementado (se esse for o uso correto do termo). Mas eu manteria isso em reserva.

Em seguida, na camada do aplicativo, consultava as tabelas de metadados para determinar onde meus dados estavam localizados e, em seguida, realizava consultas relativamente simples nas tabelas de big data para obter meus dados.

Vantagens:

  • Minha experiência (relativamente limitada) é que os bancos de dados geralmente podem lidar com um grande número de tabelas pequenas com mais facilidade do que com um número menor de tabelas grandes. Essa abordagem também facilita a manutenção (por exemplo, limpar dados antigos, reconstruir uma tabela corrompida, criar / recarregar a partir de backups, adicionar uma nova entidade). Isso desacopla completamente os diferentes tipos de dados, se (por exemplo) você tiver dados em taxas diferentes ou exigir tipos de dados diferentes.

  • Esse conceito de tabela simples também deve permitir acesso rápido ao disco para o que suspeito ser a consulta mais comum, um intervalo contíguo de dados de uma única entidade. A maioria dos aplicativos de dados tem E / S de disco limitada, portanto vale a pena considerar. Como um comentarista já sugeriu, esse pode ser um aplicativo ideal para um banco de dados orientado a colunas, mas ainda não encontrei um produto orientado a colunas que seja suficientemente amplo para que eu possa apostar em minha carreira. Esse esquema fica bem próximo.

Desvantagens:

  • Cerca de metade do espaço em disco é dedicado ao armazenamento de carimbos de data / hora, quando francamente 100 ou 1000 das tabelas terão exatamente os mesmos dados na coluna de carimbo de data / hora. (Na verdade, esse é um requisito se você deseja realizar junções fáceis na tabela).

  • Armazenar nomes de tabelas e executar a pesquisa dinâmica requer muita complexidade de aplicativo e operações de string, o que me faz estremecer. Mas ainda parece melhor do que as alternativas (discutidas abaixo).

Considerações:

  • Tenha cuidado ao arredondar no seu campo de tempo. Você deseja que seus valores sejam redondos o suficiente para permitir junções (se apropriado), mas precisos o suficiente para serem inequívocos.

  • Tenha cuidado com os fusos horários e o horário de verão. Estes são difíceis de testar. Eu aplicaria um requisito UTC no armazenamento de dados (o que pode me deixar impopular) e manipularia conversões no aplicativo.

Variações:

Algumas variações que considerei são:

Dobra de dados: se as séries temporais estiverem igualmente espaçadas, use uma coluna de carimbo de data e hora e (por exemplo) 10 colunas de dados. O registro de data e hora agora se refere ao horário da primeira coluna de dados, e as outras colunas de dados são assumidas igualmente espaçadas entre esse registro de data e hora e a próxima. Isso economiza muito armazenamento que foi usado anteriormente para armazenar registros de data e hora, a um custo significativo de consulta e / ou complexidade do aplicativo. No intervalo contíguo, as consultas de entidade única agora exigem menos acesso ao disco.

Plexo múltiplo : se for conhecido que várias séries temporais usam a mesma série, use um carimbo de data e hora e (por exemplo) 10 colunas de dados, conforme descrito acima. Mas agora cada coluna representa uma série temporal diferente. Isso requer uma atualização da tabela de metadados, que não é uma pesquisa no nome da tabela e da coluna. O espaço de armazenamento é reduzido. As consultas permanecem simples. No entanto, o alcance contíguo, as consultas de entidade única agora exigem muito mais acesso ao disco.

Mega-tabela: leve ao extremo o conceito "multi-flexibilidade" e coloque todos os dados em uma única tabela, uma vez séries temporais por coluna. Isso requer grandes quantidades de acesso ao disco para intervalo contíguo, consultas de entidade única e é um pesadelo de manutenção. Por exemplo, adicionar uma nova entidade agora requer um comando MODIFY TABLE em muitas tabelas de TB.

Para discussões adicionais sobre este formato, consulte as várias respostas em: Muitas colunas no MySQL

Tabela totalmente normalizada: em vez de usar muitas tabelas de duas colunas, você pode usar uma tabela de três colunas, onde as colunas são hora, dataid e valor. Agora, suas tabelas de metadados precisam apenas pesquisar valores de ID, em vez de nomes de tabelas ou nomes de colunas, o que permite inserir mais lógica nas consultas SQL, em vez da camada de aplicativo.

Aproximadamente 2/3 do armazenamento agora são consumidos com as colunas normalizadas, portanto, isso consumirá muito espaço em disco.

Você pode usar uma ordem de chave primária de (dataid, timestamp) para consultas rápidas e contínuas de entidade única. Ou, você pode usar uma ordem de chave primária de (timestamp. Dataid) para inserções mais rápidas.

No entanto, mesmo depois de considerar essas variações, meu plano para o meu próximo desenvolvimento são muitas tabelas, duas colunas cada. Isso ou o método que será postado em breve por alguém mais sábio do que eu :).

Perseguição
fonte
Muito obrigado pela sua resposta. Você levantou alguns pontos muito válidos. Concordo plenamente com o armazenamento no UTC. Estou reforçando a ideia de que todos os dados são entregues aos frontends (web, desktop e celular) no UTC. Temos clientes multinacionais e o sistema operacional deve ser responsável por fazer a conversão de horário. Eu tenho uma empresa de DBA trabalhando em todo o nosso conjunto de dados e me perguntei o que os outros apresentariam. Obrigado novamente.
Nicolas
Enquanto os consultores do DBA trabalharem no direcionamento de uma instalação robusta do SQL Server, eu continuarei testando com uma instalação do BigData.
Nicolas
Pode ser que seja uma boa solução, mas o aplicativo real de "séries temporais" deve suportar a funcionalidade "ampliar dados", e o banco de dados não pode ajudar com isso. Os bancos de dados de séries temporais são mais sobre "zoom in" e "zoom out" inteligentes.
Roman Pokrovskij
1

Use o MongoDB, você pode criar coleções rapidamente, rapidamente. Olhe para organizar seus dados em bancos de dados separados e coleções dentro desses bancos de dados. Considere quanta memória você precisaria para tentar manter cada fragmento na memória do sistema - se precisar de recuperação rápida. É tolice ficar com uma solução interna, se houver algo mais atual por aí que evolua ao longo das linhas de que você precisa. Parece uma boa iniciativa.

Dantalion
fonte
2
Como você armazenaria a série cronológica no Mongo? Cada documento é uma série de tempo? ou o valor de um carimbo de data / hora específico?
RockScience
Para fazer isso de forma eficiente para dados não periódicos ou mesmo periódicos, é melhor pré-alocar blocos de dados. Cada parte seria um documento com uma pequena quantidade de dados da contabilidade, uma matriz de tamanho fixo para seus valores e uma matriz de tamanho fixo para seus tempos. Você armazenaria seus metadados para a série em um documento separado. Neste documento de metadados, mantenha um pequeno documento aninhado que atuará como contador dos seus segmentos de dados, ou seja, rastreie o índice atual da matriz e o segmento _id.
RYS