Qual é uma boa maneira de armazenar um grande número de colunas?

18

Tenho um problema ao decidir como armazenar esses dados no meu banco de dados. Alguma sugestão sobre a melhor maneira de fazê-lo? Eu não sei muito sobre bancos de dados, devo acrescentar.

Eu tenho os dados no formato formatado, mas, em vez de 4, o número de colunas é de aproximadamente 240, portanto, cada data tem 240 valores exclusivos associados:

Date/Time 200,00 202,50 205,00  
2010.11.12  13:34:00  45,8214 43,8512  41,5369   
2010.11.12  13:35:00  461,9364  454,2612  435,5222 

Além disso, as linhas são associadas ao DataSites.

Meu primeiro pensamento foi ter uma tabela como esta: DataID (pk), DataSiteID, ParameterID, Date, Value, com um índice em DataSite, Parameter e Date. O ParameterID refere-se a outra tabela que armazena os cabeçalhos da coluna de entrada (200,00 202,50 205,00 ...).

Meu segundo pensamento foi simplesmente ter uma mesa com todas as 240 colunas ímpares. Eu vim com algumas outras maneiras, mas elas também são bastante insatisfatórias.

O problema que tenho com a minha primeira solução (não é um problema tão grande, mas não gosto disso) é que o Date e DataSiteID serão repetidos para todos os 240 valores nessa linha de entrada, portanto, usa um pouco de espaço extra.

Serão recebidos cerca de 40 GB de dados por ano (no formato de texto acima), e os dados serão pesquisados ​​por DataSite, Parâmetro e Data. A quantidade de dados recebidos provavelmente quadruplicará em um ano ou mais.

Alguma boa ideia? Obrigado James

editar: trata-se de dados de séries temporais, com as colunas sendo medidas em diferentes comprimentos de onda. Os dados deverão ser analisados ​​dentro de uma faixa relativamente estreita de comprimentos de onda. Também pode haver comprimentos de onda extras adicionados em algum momento no futuro.

edit: Obrigado pelas respostas pessoal, eu realmente aprecio :) Acho que provavelmente encontro tempo para executar algumas experiências com 500 GB ou mais de dados de teste. Vou postar de volta com todas as conclusões;)

James
fonte
2
A partir do nome das colunas, estou supondo que se trata de algum tipo de dado de série temporal observacional. Se esses dados são científicos, eu verificaria se a disciplina científica tem maneiras típicas de organizar seus dados, ou pelo menos quais são os casos de uso de ciências que fazem uso dos dados.
Joe
Na verdade, são dados de séries temporais :) postagem original editada com um pouco mais de informação.
James

Respostas:

10

Você poderia argumentar de qualquer maneira, mas se os dados forem usados ​​para análise e você frequentemente quiser ver várias colunas desses dados ao mesmo tempo, vá com a tabela ampla. Certifique-se de conhecer a quantidade da coluna dos bancos de dados e os limites de tamanho da linha. Certifique-se de acertar os tipos de dados. Se muitas das colunas forem nulas, o SQL Server permitirá otimizar a tabela para isso. Você também pode considerar o uso de uma solução NOSQL (não apenas SQL) para análise desse tipo de dados.

Se esses dados forem menores para análise, convém normalizá-los conforme indicado na sua pergunta.

Eric Humphrey - lotes de ajuda
fonte
6

Eu tive uma situação muito parecida com a sua, 257 campos com 30 a 50 GB por ano chegando. Acabei mantendo a simplicidade, uma longa mesa grande no SQL Server. Meus dados foram consultados um pouco, mas principalmente na data, e funcionaram bem.

Eu poderia ter dividido os dados em grupos menores lógicos (grupos de 50 ou mais), mas nesse caso realmente não havia muita vantagem nisso, então me salvei.

Se eu estivesse me sentindo bem agora, poderia considerar uma opção NoSQL que se encaixa melhor na teoria, mas com dados de missão crítica experimentar coisas novas nem sempre é bom para os nervos.

henry.oswald
fonte
6

Portanto, para responder tardiamente à minha própria pergunta (o projeto nunca foi adiante no final), quando consegui algum tempo livre, preenchi uma tabela de teste com 500 gb de dados com a tabela organizada da seguinte forma:

Meu primeiro pensamento foi ter uma tabela como esta: DataID (pk), DataSiteID, ParameterID, Date, Value, com um índice em DataSite, Parameter e Date. O ParameterID refere-se a outra tabela que armazena os cabeçalhos da coluna de entrada (200,00 202,50 205,00 ...).

A configuração do banco de dados foi a instalação padrão do PostgreSQL em uma antiga máquina dual core com 3 GB de RAM. Executei cerca de uma dúzia de consultas diferentes, simplesmente selecionando dados por DataSite Date e ParameterID, calculando a média dos dados em um período de 1 hora, 1 dia e inserindo novos blocos de dados. De memória, todas as consultas levaram menos de um segundo para serem executadas. Certamente foi muito mais rápido do que eu esperava e bastante utilizável. Uma coisa que eu não tinha pensado era que, com a tabela indexada dessa maneira, o arquivo de índice também tinha quase 500 GB, portanto, ter uma tabela com 240 colunas de largura certamente economizaria muito espaço em disco.

James
fonte
Mas, ao economizar espaço, certamente afetaria a velocidade da indexação. Você pode tentar novamente se tiver a chance e seguir em frente e girá-la.
Jcolebrand
3

No Postgres, eu resolvia isso elegantemente com um tipo de matriz ou um varray no Oracle.

Gaius
fonte
Isso funcionaria, o único problema é que eu precisaria armazenar os cabeçalhos das colunas para o DataSite em algum lugar, pois sem ele os dados não significam nada e eles podem variar / mudar (eles não deveriam, mas eu devo ' vi os porcos voam antes ...)
James
Nesse caso, na minha tabela de dados principal, eu teria outra coluna chamada "version" e outra versão de mapeamento de tabela para uma matriz de títulos de coluna (para que os índices da matriz correspondam à matriz de dados).
Gaius
3

Não sei se é útil para o seu problema, mas para as colunas em que não preciso fazer solicitações diretas (colunas que eu nunca coloquei na minha condição WHERE) e que são apenas informativas quando quero todas as informações sobre alguns linhas específicas, eu as combinei em um campo de blog formatado em JSON.


fonte
Além disso, comprima esse blob. Faça a compactação no cliente, para não sobrecarregar a rede e o servidor.
Rick James
2

Provavelmente, eu tomaria a decisão final do design dependente da distribuição dos parameter_ids consultados. Ou seja, se houver alguns parâmetro_ids consultados quase que exclusivamente, eu colocaria seus valores em uma tabela ativa e os demais em outra tabela fria .

Otoh, se a distribuição de consultas for mais ou menos uniforme, eu carregaria um conjunto de amostras que vale alguns dias em uma tabela em que um registro mantém todos os valores para ver qual é a proporção entre registros / blocos de banco de dados (ou se existe até um problema de encadeamento de linhas , o que é provável). Dependendo disso, eu tomaria outra decisão de design.

Bem, depois de ler, eu provavelmente faria as duas abordagens por uma intenção em paralelo.

René Nyffenegger
fonte
2

Eu estava relendo a pergunta - se eu tiver isso correto, em cada registro que você obtém como entrada, há diferentes valores sendo rastreados (com base no ParameterID):

O ParameterID refere-se a outra tabela que armazena os cabeçalhos da coluna de entrada (200,00 202,50 205,00 ...).

... Eu não sei o suficiente sobre como você está interagindo com os dados, mas estaria inclinado a optar por outra opção - ter uma tabela separada para cada ID de parâmetro e, se necessário, ter uma visão que junte os vários parâmetros diferentes por data e local na tabela mais ampla (240 colunas); se fosse importante manter o DataID acessível na exibição, você poderia usar um em UNIONvez de um JOIN, mas as colunas serão escassamente preenchidas.

Joe
fonte
Por parâmetro, quero dizer o cabeçalho da coluna, ou comprimento de onda. Eu tinha pensado em fazê-lo desta maneira, mas com 240 mesas sente um desajeitado pouco :)
James
@ James ... não deve ser 240 mesas ... apenas o número de ParameterIDs únicos . A visualização seria tão ampla quanto o número de comprimentos de onda discretos nos quais você tem medidas (mais as variáveis ​​independentes). ... Talvez você queira ver como a comunidade OPeNDAP lida com as coisas, pois elas são voltadas para dados de séries temporais. A maioria dos dados com os quais lido são imagens (telescópio, coronógrafo, magnetógrafo), para que o material deles não se encaixe no meu trabalho, então não sei como eles lidam com o armazenamento. (podem ser apenas tabelas HDF / CDF / NetCDF / ASCII).
Joe
Infelizmente, existem parâmetros únicos 240-ish :( Obrigado pelo link :)
James
@ James: também, são dados de irradiância? Nesse caso, você pode perguntar ao pessoal da LISIRD ... Acho que eles o separam em conjuntos separados de dados por experimento, e não sei se eles o mantêm em bancos de dados ou apenas em arquivos simples.
Joe