Da keine Antworten vorliegen, habe ich das Problem selbst weiter untersucht.
Es sieht so aus, als könnten benutzerdefinierte Funktionen alle Basistypen verarbeiten, einschließlich bytea
und smallint[]
, sodass die Auswahl der Darstellung nicht wesentlich beeinflusst wird.
Ich habe verschiedene Darstellungen auf einem PostgreSQL 9.4-Server ausprobiert, der lokal auf einem Windows 7-Laptop mit Vanille-Konfiguration ausgeführt wird. Die Beziehungen zum Speichern dieser tatsächlichen Signaldaten waren wie folgt.
Großes Objekt für die gesamte Datei
CREATE TABLE BlobFile (
eeg_id INTEGER PRIMARY KEY,
eeg_oid OID NOT NULL
);
SMALLINT-Array pro Kanal
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 pro Kanal in jeder Epoche
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 pro Epoche
CREATE TABLE EpochArray (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals SMALLINT[][] NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
BYTEA-Array pro Epoche
CREATE TABLE EpochBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);
Ich habe dann eine Auswahl von EDF-Dateien über Java JDBC in jede dieser Beziehungen importiert und das Wachstum der Datenbankgröße nach jedem Upload verglichen.
Die Dateien waren:
- Datei A: 2706 Epochen mit 16 Kanälen, jeder Kanal 1024 Samples (16385 Samples pro Epoche), 85 MB
- Datei B: 11897 Epochen mit 18 Kanälen, jeder Kanal 1024 Samples (18432 Samples pro Epoche), 418 MB
- Datei C: 11746 Epochen mit 20 Kanälen, jeder Kanal 64 bis 1024 Samples (17088 Samples pro Epoche), 382 MB
In Bezug auf die Speicherkosten ist hier die Größe in MB für jeden Fall belegt:
Im Vergleich zur ursprünglichen Dateigröße waren große Objekte etwa 30-35% größer. Im Gegensatz dazu war die Speicherung jeder Epoche als BYTEA oder SMALLINT [] [] weniger als 10% größer. Das Speichern jedes Kanals als separates Tupel ergibt eine 40% ige Erhöhung, entweder als BYTEA oder SMALLINT [], also nicht viel schlimmer als das Speichern als großes Objekt.
Eine Sache, die ich anfangs nicht gewürdigt hatte, ist, dass "Mehrdimensionale Arrays für jede Dimension übereinstimmende Ausmaße haben müssen" in PostgreSQL . Dies bedeutet, dass die SMALLINT[][]
Darstellung nur funktioniert, wenn alle Kanäle in einer Epoche die gleiche Anzahl von Samples haben. Daher funktioniert Datei C nicht mit der EpochArray
Beziehung.
In Bezug auf die Zugriffskosten habe ich nicht damit herumgespielt, aber zumindest in Bezug auf das Einfügen der Daten war anfangs die schnellste Darstellung EpochBytea
und BlobFile
mit EpochChannelArray
der langsamsten etwa dreimal so lange wie die ersten beiden.