In assenza di risposte ho approfondito il problema da solo.
Sembra che le funzioni definite dall'utente possano gestire tutti i tipi di base, incluso bytea
e smallint[]
, quindi ciò non influisce molto sulla scelta della rappresentazione.
Ho provato diverse rappresentazioni su un server PostgreSQL 9.4 eseguito localmente su un laptop Windows 7 con una configurazione vanilla. Le relazioni per memorizzare i dati del segnale effettivo erano le seguenti.
Oggetto di grandi dimensioni per l'intero file
CREATE TABLE BlobFile (
eeg_id INTEGER PRIMARY KEY,
eeg_oid OID NOT NULL
);
Matrice SMALLINT per canale
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 per canale in ogni epoca
CREATE TABLE EpochChannelBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
channel INT,
signal BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch, channel)
);
Matrice 2D SMALLINT per epoca
CREATE TABLE EpochArray (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals SMALLINT[][] NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
Matrice BYTEA per epoca
CREATE TABLE EpochBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
Ho quindi importato una selezione di file EDF in ciascuna di queste relazioni tramite Java JDBC e ho confrontato la crescita delle dimensioni del database dopo ogni caricamento.
I file erano:
- File A: 2706 epoche di 16 canali, ogni canale 1024 campioni (16385 campioni per epoca), 85 MB
- File B: 11897 epoche di 18 canali, ogni canale 1024 campioni (18432 campioni per epoca), 418 MB
- File C: 11746 epoche di 20 canali, ogni canale da 64 a 1024 campioni (17088 campioni per epoca), 382 MB
In termini di costi di archiviazione, ecco la dimensione occupata in MB per ogni caso:
Rispetto alle dimensioni del file originale, gli oggetti grandi erano circa il 30-35% più grandi. Al contrario, la memorizzazione di ogni epoca come BYTEA o SMALLINT [] [] era inferiore di oltre il 10%. La memorizzazione di ciascun canale come tupla separata aumenta del 40%, come BYTEA o SMALLINT [], quindi non molto peggio della memorizzazione come oggetto di grandi dimensioni.
Una cosa che inizialmente non avevo apprezzato è che "gli array multidimensionali devono avere estensioni corrispondenti per ogni dimensione" in PostgreSQL . Ciò significa che la SMALLINT[][]
rappresentazione funziona solo quando tutti i canali di un'epoca hanno lo stesso numero di campioni. Quindi il file C non funziona con la EpochArray
relazione.
In termini di costi di accesso, non ci ho giocato, ma almeno per quanto riguarda l'inserimento dei dati inizialmente la rappresentazione più veloce era EpochBytea
e BlobFile
, con EpochChannelArray
la più lenta, impiegava circa 3 volte più delle prime due.