Na ausência de respostas, eu também explorei a questão.
Parece que as funções definidas pelo usuário podem lidar com todos os tipos de base, incluindo bytea
e smallint[]
, portanto, isso não afeta muito a escolha da representação.
Tentei várias representações diferentes em um servidor PostgreSQL 9.4 em execução localmente em um laptop Windows 7 com uma configuração de baunilha. As relações para armazenar os dados reais do sinal foram as seguintes.
Objeto grande para o arquivo inteiro
CREATE TABLE BlobFile (
eeg_id INTEGER PRIMARY KEY,
eeg_oid OID NOT NULL
);
Matriz SMALLINT por canal
CREATE TABLE EpochChannelArray (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
channel INT,
signal SMALLINT[] NOT NULL,
PRIMARY KEY (eeg_id, epoch, channel)
);
BYTEA por canal em cada época
CREATE TABLE EpochChannelBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
channel INT,
signal BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch, channel)
);
Matriz 2D SMALLINT por época
CREATE TABLE EpochArray (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals SMALLINT[][] NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
Matriz BYTEA por época
CREATE TABLE EpochBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
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:
- Arquivo A: 2706 épocas de 16 canais, cada canal 1024 amostras (16385 amostras por época), 85 MB
- Arquivo B: 11897 épocas de 18 canais, cada canal 1024 amostras (18432 amostras por época), 418 MB
- Arquivo C: 11746 épocas de 20 canais, cada canal de 64 a 1024 amostras (17088 amostras por época), 382 MB
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, o armazenamento de cada época como BYTEA ou SMALLINT [] [] era menos de 10% maior. Armazenar cada canal como uma tupla separada gera um aumento de 40%, como BYTEA ou SMALLINT [], portanto não é muito pior do que armazenar como um objeto grande.
Uma coisa que eu não havia apreciado inicialmente é que "matrizes 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 falha ao trabalhar com a EpochArray
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
e BlobFile
, com EpochChannelArray
a mais lenta, demorou cerca de três vezes o tempo das duas primeiras.