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.
Respostas:
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:
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 :).
fonte
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.
fonte