Estou procurando importar dados de série temporal multicanal grandes (100 MB - 1 GB) para um banco de dados PostgreSQL. Os dados vêm de arquivos no formato EDF que dividem os dados em "registros" ou "épocas" de alguns segundos cada. O registro de cada época contém os sinais para cada canal de dados como matrizes sequenciais de inteiros curtos.
Sou obrigado a armazenar os arquivos no banco de dados, no pior dos casos, como BLOBs. Diante disso, gostaria de investigar opções que me permitissem fazer algo mais com os dados do banco de dados, como facilitar consultas com base nos dados do sinal.
Meu plano inicial é armazenar os dados como uma linha por registro de época. O que estou tentando avaliar é se devo armazenar os dados do sinal real como tipos bytea ou smallint[] (ou mesmo smallint[][]). Alguém poderia recomendar um sobre o outro? Estou interessado nos custos de armazenamento e acesso. É provável que o uso seja inserido uma vez, lido ocasionalmente, nunca atualizado. Se um fosse mais facilmente agrupado como um tipo personalizado, de modo que eu pudesse adicionar funções para analisar ou comparar registros, tanto melhor.
Sem dúvida, estou com poucos detalhes, então sinta-se à vontade para adicionar comentários sobre o que você gostaria que eu esclarecesse.
Na ausência de qualquer resposta, eu mesmo explorei mais a questão.
Parece que as funções definidas pelo usuário podem lidar com todos os tipos básicos, incluindo
bytea
esmallint[]
, portanto, isso não afeta muito a escolha da representação.Experimentei várias representações diferentes em um servidor PostgreSQL 9.4 executado localmente em um laptop com Windows 7 com uma configuração padrão. As relações para armazenar esses dados de sinal reais foram as seguintes.
Objeto grande para arquivo inteiro
Array SMALLINT por canal
BYTEA por canal em cada época
Matriz SMALLINT 2D por época
Matriz BYTEA por época
Em seguida, importei uma seleção de arquivos EDF para cada uma dessas relações via Java JDBC e comparei o crescimento no tamanho do banco de dados após cada upload.
Os arquivos foram:
Em termos de custo de armazenamento, eis o tamanho ocupado em MB para cada caso:
Em relação ao tamanho do arquivo original, os Objetos Grandes eram cerca de 30 a 35% maiores. Por outro lado, armazenar cada época como BYTEA ou SMALLINT[][] foi menos de 10% maior. Armazenar cada canal como uma tupla separada dá um aumento de 40%, como BYTEA ou SMALLINT[], portanto, não é muito pior do que armazenar como um objeto grande.
Uma coisa que inicialmente não apreciei é que "arrays multidimensionais devem ter extensões correspondentes para cada dimensão" no PostgreSQL . Isso significa que a
SMALLINT[][]
representação só funciona quando todos os canais de uma época têm o mesmo número de amostras. Portanto, o Arquivo C não funciona com aEpochArray
relação.Em termos de custos de acesso, não brinquei com isso, mas pelo menos em termos de inserir os dados inicialmente a representação mais rápida foi
EpochBytea
eBlobFile
, comEpochChannelArray
a mais lenta, demorando cerca de 3 vezes mais que as duas primeiras.