在 PostreSQL 中存储 UniProt 生物序列的最佳方式是什么?
数据详情
- 我们从UniProt中提取了 1200 万个序列——这个数字可能每 3-10 个月翻一番。
- 序列的长度可以从 10 到 500 亿个字符不等
- 不到 1% 的序列长度超过 10,000 个字符
- 单独存储较长的序列会提高性能吗?
- 序列可以是蛋白质或 DNA 字母表
- DNA 字母表有 5 个字符(A、T、C、G 或 -)。
- 蛋白质字母表将包含大约 30 个字符。
- 我们不介意将两个不同字母表的序列存储在不同的列甚至不同的表中。那会有帮助吗?
数据访问详细信息
回答 Jeremiah Peschka 的评论:
- 蛋白质和 DNA 序列将在不同时间访问
- 不需要在序列内搜索(这是在数据库之外完成的)
- 以太一次访问单行或通过 ID 提取行集。我们不需要扫描行。所有序列都由其他表引用 - 数据库中存在几个具有生物学和时间顺序意义的层次结构。
向后兼容性
如果能够继续能够将以下哈希函数(SEGUID - 序列全球唯一标识符)应用于序列,那就太好了。
CREATE OR REPLACE FUNCTION gfam.get_seguid(p_sequence character varying)
RETURNS character varying AS
$BODY$
declare
result varchar := null;
x integer;
begin
select encode(gfam.digest(p_sequence, 'sha1'), 'base64')
into result;
x := length(result);
if substring(result from x for 1) = '=' then
result := substring( result from 1 for x-1 );
end if;
return result;
end;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;
探索PostBio的功能,看起来他们有几种编码方式。但是,鉴于这些扩展针对搜索进行了优化,它们会多次引用以简单地使用
text
数据类型。根据文档:
因此,通过将表放入专用硬件上它自己的非常大的表空间应该足以满足您的性能目标。如果 1 GB 对于您的数据来说太小,ProtBio 的 int_interval 应该提供出色的性能:
考虑到序列的潜在长度,在 sha1 中编码序列看起来是制作 GUID 的一种非常痛苦的方式。
如果不同的序列不相关,则将它们存储在不同磁盘上的不同表空间中以获得最佳性能。
我认为 500 亿个字符可能会突破您使用 PostgreSQL 可以做的事情的极限,而无需以某种方式拆分您的记录。我怀疑您将不得不找到某种方法以某种方式将事物分开。我不知道 postbio 允许什么样的编码,但是......
此处快速计算:5 个字符需要 3 位进行编码,但 4 位将使搜索更容易,因为每个字节可以编码两个字符。另一方面,如果您正在搜索 10 个或更多字母的组,则 3 个可能就足够了,因为您可以每 4 个字节搜索 10 个字符。针对短字符串搜索进行了如此优化,500 亿个字符需要大约 25GB 的存储空间,远远超出您在单个列中可以执行的操作。压缩可能会有所帮助,但这是超出最小未压缩二进制表示形式所需的巨大压缩规模为了降低到1GB。针对更长的搜索进行了优化,我们只有 20GB。所以我认为即使你有遗传信息类型,你也会把事情分开。如此复杂的蛋白质将更具挑战性,因为您可以期望的最好的是 5 位表示法,这意味着每 32 个有 6 个,这意味着您最好的存储情况是每列 30GB。因此,除非您可以获得 Compression 可能会再次有所帮助,但这需要很大的压缩率。我见过不错的压缩率,但请记住,您可能正在推动它。
所以我的建议是注意这个问题,并用真实数据做一些测试。在某些情况下,请准备好分解您的读数。