我正在研究生物实验室,我必须设计一个数据库,以便存储许多DNA微阵列实验结果。
每个实验由许多微阵列(平均约10个)组成,每个微阵列含有超过5百万个探针。每个探针都映射到特定的基因id,当然在所有实验中相同的探针匹配相同的gene_id。目的是存储每个微阵列的强度值,以便能够在特定实验中快速检索特定基因id探针的强度值。
实际上一个简单的mysql表就足够了,它看起来就像那样:
强度表: | probe_id | EXPERIMENT_ID | microarray_id | gene_id | intensity_value
主键由(probe_id,experiment_id,microarray_id,gene_id)组成
这是问题:每个实验都有许多微阵列,其中有超过5百万个探针。通过1000次实验,平均10个微阵列(估计值很低,有些有数百个),其1000 * 10 * 5M = 50亿行。我想这会很慢。我完全不知道如何处理数十亿行的mysql表。那可能吗 ?有什么提示吗?
我也对noSQL数据库感到好奇。我从未使用过cassandra,但在我看来,这对于这项任务来说是完美的,我是对的吗?我可以想象这样的一个谢谢:
{
experiment_id_1:{ <- thats a super collumnFamilly ?
gene_id_1:{ <- thats a collumnFamilly ?
probe_id_1:{ value_microarray_1, value_microarray_2, ... }, <- thats a superCollumn ?
probe_id_2:{ value_microarray_1, value_microarray_2, ... },
probe_id_3:{ value_microarray_1, value_microarray_2, ... },
...
},
gene_id_2:{
probe_id_1:{ value_microarray_1, value_microarray_2, ... },
probe_id_2:{ value_microarray_1, value_microarray_2, ... },
probe_id_3:{ value_microarray_1, value_microarray_2, ... },
...
}
}
experiment_id_2{
...
}
...
}
我是否适合?它适合cassandra模型吗?会有效吗?你觉得noSQL大师怎么样:))
感谢。
答案 0 :(得分:2)
我认为在这种方法中也是NoSQL数据库的关系。如果您做了一些考虑,您将能够检查您是否能够处理数据:
如果我必须处理这种情况,我通常会生成一些测试数据,这些测试数据与我期望在我的表中使用的测试数据类似,并使用不同的服务器参数进行播放。此外,我考虑在这种情况下使用partitioning of tables(例如,在experiment_id上进行分区。这将导致表分割为较小的子集,可以通过现有的硬件边界来处理。你不敢这样做MySQL可以自己为你做这个,并且表格将作为单个表格呈现给用户。但是机器只需要处理存储给定experiment_id的数据集的部分。这样可以更快地实现等等。
我已经看过很容易处理表格的机器比你预期的行数要多,但你必须仔细规划这些设置,通常需要进行大量的测试/优化/重新设计才能投入生产。但是总是值得采取这种努力,因为这是一个非常有趣的事情。
(我在学习期间处理embl数据时,我在这个领域的第一次经历,这成了我的热情;)
答案 1 :(得分:1)
考虑一下:
为每个实验准备一个表,其中包含列(probe_id,gene_id,array_of_values)。如果我理解正确,主键将在probe_id上(但如果您不查询此列,则可能没有主键)。此外,您需要一个gene_id索引。
因此,您有1000个可管理的5M行表。好还是不好?这适合您的查询模式吗?这种方案的一个优点是它可以很容易地删除旧数据。
顺便说一句,如果你考虑使用postgresql而不是mysql,它有本机数组类型。否则你应该找到一种有效的序列化数组的方法。无论如何,这应该很容易测试。
答案 2 :(得分:1)
RDBMS根本不应该使用该卷。您的数据结构足够合理,可以充分发挥关系。
MySQL取决于你的存储可以处理这个。我可能会建议将表分区放在单独的表中,只是从存储管理位置。
答案 3 :(得分:1)
MySQL或Postgres可能对你很好,其他答案给了你一些关于如何做到这一点的好建议。但是,既然你也特别询问了卡桑德拉,我的想法就是这样:
Cassandra会为此工作得很好。如果您希望能够有效地查找实验/ gene_id组合的所有强度值,我建议的内容与您提出的内容略有不同。如果您想保持简单,请使用(<experiment_id>, <gene_id>)
之类的复合键(或只是"<experiment_id>:<gene_id>"
之类的字符串),并在此行中使用每个强度值一列。这样您就可以非常有效地获取所需的所有强度值;通常一个或两个磁盘寻找冷查找。
答案 4 :(得分:0)
也许我错过了一些东西,但你的系统听起来像是:
这听起来更像是关系数据库(MySQL或PostreSQL)而不是NoSQL数据库的良好候选者 - NoSQL数据库在处理异构数据库方面要好得多。
答案 5 :(得分:0)
我熟悉这个模型,因为这是我在2010年获得博士学位的建议之一。但是,我正在研究~80000个实验(这只是Gene Expression Omnibus数据库的一小部分)。
你有一个典型的n:m基数。如果您的要求涵盖相同类型的微阵列,则需要三个表:探针(由微阵列制造商提供的探针列表),测定(一个涉及一个微阵列的实验)和测量(探针的关键,实验的关键,原始值,标准化)价值,p值等)。
如果您的查询是通过实验或通过探测进行的,那么NoSQL将起作用。这意味着,获取探针的所有值(在所有实验中)与获取实验的所有探针是互斥的。如果你想使用任何NoSQL工具(包括Cassandra),你需要存储两次数据。
另一方面,卷不是很大,以防止将其存储在一个节点上。例如,80k实验X 5M探测器X每个记录100个字节= 40TB,您可以通过具有12x6GTB = 60TB的RAID6系统来覆盖 (2个磁盘减去冗余)。
由于您可能需要一次实验或探测的所有值,因此另一个选择是使用平面文件。第一组是您的输入数据,第二组是您必须通过查询数据库来编译的。为了避免扩展磁盘搜索,以物理上的两种结构存储数据可能是成功的唯一方法。