En l’absence de réponses, j’ai moi-même approfondi la question.
Il semble que les fonctions définies par l'utilisateur puissent gérer tous les types de base, y compris bytea
et smallint[]
, donc cela n'affecte pas beaucoup le choix de la représentation.
J'ai essayé plusieurs représentations différentes sur un serveur PostgreSQL 9.4 fonctionnant localement sur un ordinateur portable Windows 7 avec une configuration vanille. Les relations pour stocker ces données de signal réelles étaient les suivantes.
Grand objet pour tout le fichier
CREATE TABLE BlobFile (
eeg_id INTEGER PRIMARY KEY,
eeg_oid OID NOT NULL
);
Réseau SMALLINT par 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 par canal à chaque époque
CREATE TABLE EpochChannelBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
channel INT,
signal BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch, channel)
);
Tableau 2D SMALLINT par époque
CREATE TABLE EpochArray (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals SMALLINT[][] NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
Tableau BYTEA par époque
CREATE TABLE EpochBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
J'ai ensuite importé une sélection de fichiers EDF dans chacune de ces relations via Java JDBC et comparé la croissance de la taille de la base de données après chaque téléchargement.
Les fichiers étaient:
- Fichier A: 2706 époques de 16 canaux, chaque canal 1024 échantillons (16385 échantillons par époque), 85 Mo
- Fichier B: 11897 époques de 18 canaux, chaque canal 1024 échantillons (18432 échantillons par époque), 418 Mo
- Fichier C: 11746 époques de 20 canaux, chaque canal 64 à 1024 échantillons (17088 échantillons par époque), 382 Mo
En termes de coût de stockage, voici la taille occupée en Mo pour chaque cas:
Par rapport à la taille du fichier d'origine, les gros objets étaient environ 30 à 35% plus grands. En revanche, le stockage de chaque époque en tant que BYTEA ou SMALLINT [] [] était inférieur de 10%. Le stockage de chaque canal en tant que tuple séparé donne une augmentation de 40%, soit BYTEA soit SMALLINT [], donc pas pire que le stockage en tant que grand objet.
Une chose que je n'avais pas appréciée au départ est que "les tableaux multidimensionnels doivent avoir des extensions correspondantes pour chaque dimension" dans PostgreSQL . Cela signifie que la SMALLINT[][]
représentation ne fonctionne que lorsque tous les canaux d'une époque ont le même nombre d'échantillons. Par conséquent, le fichier C ne fonctionne pas avec la EpochArray
relation.
En termes de coûts d'accès, je n'ai pas joué avec cela, mais au moins en termes d'insertion des données, la représentation la plus rapide était au départ EpochBytea
et BlobFile
, avec EpochChannelArray
la plus lente, cela prenait environ 3 fois plus longtemps que les deux premières.