Estoy buscando importar datos grandes (100Mb - 1 GB) de series de tiempo multicanal en una base de datos PostgreSQL. Los datos provienen de archivos en formato EDF que los agrupan en "registros" o "épocas" de unos pocos segundos cada uno. El registro de cada época contiene las señales para cada canal de datos como matrices secuenciales de enteros cortos.
Tengo el mandato de almacenar los archivos dentro de la base de datos, en el peor de los casos como BLOB. Dado eso, me gustaría investigar opciones que me permitan hacer algo más con los datos dentro de la base de datos, como facilitar consultas basadas en los datos de la señal.
Mi plan inicial es almacenar los datos como una fila por registro de época. Lo que intento sopesar es si almacenar los datos de la señal real como bytea o smallint [] (o incluso smallint [] []). ¿Alguien podría recomendar uno sobre el otro? Estoy interesado en los costos de almacenamiento y acceso. Es probable que el uso se inserte una vez, se lea ocasionalmente y nunca se actualice. Si uno se envolviera más fácilmente como un tipo personalizado de modo que pudiera agregar funciones para analizar y comparar registros, mucho mejor.
Sin duda no tengo muchos detalles, así que siéntase libre de agregar comentarios sobre lo que desea que aclare.
fuente
Respuestas:
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
ysmallint[]
, 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
Matriz SMALLINT por canal
BYTEA por canal en cada época
SMALLINT 2D array por época
Conjunto de BYTEA por época
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:
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 laEpochArray
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
yBlobFile
, conEpochChannelArray
la más lenta, tardó aproximadamente 3 veces más que las dos primeras.fuente