我希望将大型(100 GB 1GB)多通道时间序列数据导入到PostgreSQL数据库中。这些数据来自EDF格式文件,这些文件将数据分成“记录”或“时代”,通常每段时间为几秒钟。每个时代的记录都以短整数序列数组的形式保存每个数据通道的信号。
我的任务是将文件存储在数据库中,在最坏的情况下作为BLOB存储。考虑到这一点,我想研究一些选项,这些选项允许我对数据库中的数据做更多的事情,比如基于信号数据的查询。
我的最初计划是将数据存储为每一个时代记录的一行。我试图权衡的是,是将实际的信号数据存储为由the还是smallint甚至smallint[][]类型。有人能推荐一个吗?我对存储和存取费用感兴趣。用法可能是插入一次,偶尔阅读,从不更新。如果更容易将其封装为自定义类型,那么我就可以添加分析记录比较的功能,那么越好越好。
毫无疑问,我在细节上很低,所以可以随意添加评论,你想让我澄清什么。
发布于 2015-06-25 05:27:27
在没有任何答案的情况下,我自己进一步探讨了这个问题。
看起来用户定义函数可以处理所有的基本类型,包括、bytea和smallint[],所以这不会对表示的选择产生太大的影响。
我在一个本地运行的带有普通配置的Windows7笔记本电脑上的PostgreSQL 9.4服务器上尝试了几种不同的表示形式。实际信号数据的存储关系如下。
用于整个文件的
CREATE TABLE BlobFile (
eeg_id INTEGER PRIMARY KEY,
eeg_oid OID NOT NULL
);阵列
CREATE TABLE EpochChannelArray (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
channel INT,
signal SMALLINT[] NOT NULL,
PRIMARY KEY (eeg_id, epoch, channel)
);CREATE TABLE EpochChannelBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
channel INT,
signal BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch, channel)
);CREATE TABLE EpochArray (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals SMALLINT[][] NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);CREATE TABLE EpochBytea (
eeg_id INT NOT NULL,
epoch INT NOT NULL,
signals BYTEA NOT NULL,
PRIMARY KEY (eeg_id, epoch)
);然后,我通过Java将一些EDF文件导入到这些关系中,并比较了每次上传后数据库大小的增长情况。
这些档案是:
就存储成本而言,以下是每种情况下所占用的MB大小:

相对于原始文件大小,较大的对象大约大30-35% .相反,将每个时代存储为BYTEA或SMALLINTundefined都小于10%。将每个通道作为一个单独的元组存储会增加40%,无论是BYTEA还是SMALLINT[],都不会比作为一个大对象的存储更糟糕。
我一开始没有意识到的一件事是,“多维数组必须对每个维度都有匹配的区段”在PostgreSQL中。这意味着SMALLINT[][]表示只在一个时代中的所有通道都有相同数量的样本时才能工作。因此,文件C无法处理EpochArray关系。
就访问成本而言,我没有尝试过这一点,但至少在最初插入数据方面,最快的表示形式是EpochBytea和BlobFile,而EpochChannelArray是最慢的,花费的时间大约是前两次的3倍。
https://dba.stackexchange.com/questions/102456
复制相似问题