En ausencia de respuestas, he explorado el tema más yo mismo.
Parece que las funciones definidas por el usuario pueden manejar todos los tipos base, incluidos bytea
y smallint[]
, por lo que esto no afecta mucho la elección de la representación.
Probé varias representaciones diferentes en un servidor PostgreSQL 9.4 que se ejecuta localmente en una computadora portátil Windows 7 con una configuración estándar. Las relaciones para almacenar esos datos de señal reales fueron las siguientes.
Objeto grande para todo el archivo
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 en 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)
);
SMALLINT 2D array por época
CREATE TABLE EpochArray (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals SMALLINT[][] NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
Conjunto de BYTEA por época
CREATE TABLE EpochBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
Luego importé una selección de archivos EDF en cada una de estas relaciones a través de Java JDBC y comparé el crecimiento del tamaño de la base de datos después de cada carga.
Los archivos fueron:
- Archivo A: 2706 épocas de 16 canales, cada canal 1024 muestras (16385 muestras por época), 85 MB
- Archivo B: 11897 épocas de 18 canales, cada canal 1024 muestras (18432 muestras por época), 418 MB
- Archivo C: 11746 épocas de 20 canales, cada canal de 64 a 1024 muestras (17088 muestras por época), 382 MB
En términos de costo de almacenamiento, aquí está el tamaño ocupado en MB para cada caso:
En relación con el tamaño del archivo original, los objetos grandes eran aproximadamente un 30-35% más grandes. Por el contrario, almacenar cada época como BYTEA o SMALLINT [] [] era menos del 10% más grande. El almacenamiento de cada canal como una tupla separada proporciona un aumento del 40%, ya sea BYTEA o SMALLINT [], por lo que no es mucho peor que almacenarlo como un objeto grande.
Una cosa que no había apreciado inicialmente es que "las matrices multidimensionales deben tener extensiones coincidentes para cada dimensión" en PostgreSQL . Esto significa que la SMALLINT[][]
representación solo funciona cuando todos los canales de una época tienen el mismo número de muestras. Por lo tanto, el archivo C no funciona con la EpochArray
relación.
En términos de costos de acceso, no he jugado con esto, pero al menos en términos de insertar los datos inicialmente, la representación más rápida fue EpochBytea
y BlobFile
, con EpochChannelArray
la más lenta, tardó aproximadamente 3 veces más que las dos primeras.