5

我在一个生物实验室工作,我必须设计一个数据库来存储许多 DNA 微阵列实验结果。

每个实验由许多微阵列(平均约十个)组成,每个微阵列包含超过 500 万个探针。每个探针都映射到一个特定的基因 id,当然,在所有实验中,相同的探针匹配相同的基因 ID。目的是存储每个微阵列的强度值,以便能够在特定实验中快速检索特定基因 id 的探针的强度值。

事实上,一个简单的 mysql 表就足够了,它看起来像这样:

强度表:|probe_id|experiment_id|microarray_id|gene_id|intensity_value

主键由(probe_id、experiment_id、microarray_id、gene_id)组成

问题是:每个实验都有许多微阵列,其中有超过 500 万个探针。1000 次实验,平均 10 个微阵列(这是一个低估计,有些有数百个),它的 1000 * 10 * 5M = 500 亿行。我想它会很慢。而且我完全不知道如何处理数十亿行的 mysql 表。那可能吗 ?有小费吗 ?

我也对 noSQL 数据库很好奇。我从未使用过 cassandra,但在我看来它非常适合这项任务,对吗?我可以想象这样的shema:

{
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大师:)

谢谢。

4

6 回答 6

2

我会考虑在这种方法中也是基于 NoSQL 数据库的关系。如果您做出一些考虑,您将能够检查您是否能够处理数据:

  1. 表的预期大小是多少,大致了解检查一组数据的大小并通过将其乘以数据集的总预期数量来计算总体大小。
  2. 计算索引的大小
  3. 现在检查,如果您的服务器能够在 RAM 中处理这些索引或更好,请在 RAM 中处理整个表。
  4. 此表上的 DML/选择操作之间的比率是多少
  5. 确保你有适当的策略来处理常见的任务,比如备份、优化、更改这些类型的表。

如果我必须处理哪种情况,我通常会生成一些测试数据,这些数据与我希望在我的表中拥有的数据相似,并使用不同的服务器参数进行调整。另外我考虑在这种情况下使用表分区(例如在实验ID上进行分区。这将导致表拆分为更小的子集,这可以通过现有的硬件边界来处理。你不敢自己做这个, MySQL 可以为您执行此操作,并且该表将作为单个表呈现给用户。但是机器只需要处理存储给定实验 ID 的数据集的部分。这会导致更快的 I/O 等.

我已经看到机器可以轻松处理比您预期的行数多得多的表,但是您必须仔细计划此类设置,并且通常需要进行大量测试/优化/重新设计才能投入生产。但付出这种努力总是值得的,因为这是一件非常有趣的事情。

(我在学习期间处理 embl 数据时获得了该领域的第一次体验,这成为了我的热情;))

于 2012-04-05T15:02:37.567 回答
1

MySQL 或 Postgres 可能适合您,其他答案为您提供了一些关于如何做到这一点的好技巧。但是,由于您也专门询问了 Cassandra,所以我的想法如下:

Cassandra 可以很好地解决这个问题。如果您希望能够有效地查找实验/gene_id 组合的所有强度值,我建议您使用与您想出的略有不同的方法。使用复合键(<experiment_id>, <gene_id>)(或仅使用字符串,"<experiment_id>:<gene_id>"如果您想保持简单),并在该行中的每个强度值使用一列。这将使您可以非常有效地获取所需的所有强度值;通常一个或两个磁盘寻找冷查找。

于 2012-04-06T02:09:48.330 回答
1

RDBMS 根本不应该被那个卷阻塞。您的数据结构足够结构化,足以将其放入关系中。

MySQL 取决于您的存储可以处理这个问题。我可能会建议通过将它们放入单独的表中来进行表分区,只是从存储管理位置。

相关数据库中有多少行太多了?

于 2012-04-05T14:53:21.733 回答
1

Consider this:

Have a table for each experiment, which has columns (probe_id, gene_id, array_of_values). If I understood You correctly, the primary key would be on probe_id (but If You don't query this column, You could just not have a primary key). Also, You need an index on gene_id.

Thus, You have 1000 tables of manageable 5M rows each. good or not? Does this fit Your query patterns? A neat property of this scheme is that it makes it easy to drop old data.

BTW, if You consider postgresql instead of mysql, it has native array types. Otherwise You should figure out an efficient method of serializing the arrays.

Anyway, this should be easy to test.

于 2012-04-05T14:39:41.793 回答
0

也许我错过了一些东西,但你有一个听起来像这样的系统:

  • 同质:数据库中的每个条目都有一个实验 ID、一个基因 ID、一个探针 ID、一个值选择器 ID(它是微阵列的哪个元素)和一个值。
  • 一次写入,多次读取:您将记录信息,一旦记录下来,您就再也不想更改它。

这听起来更像是关系数据库(MySQL 或 PostreSQL)而不是 NoSQL 数据库的良好候选者——NoSQL 数据库在处理异构数据库方面要好得多。

于 2012-04-05T13:59:44.123 回答
0

我对这个模型很熟悉,因为这是我 2010 年的博士提案之一。但是,我正在查看大约 80000 个实验(这只是基因表达综合数据库的一小部分)。

你有一个典型的 n:m 基数。如果您的要求涵盖相同类型的微阵列,则需要三个表格:探针(微阵列制造商提供的探针列表)、测定(一个实验涉及一个微阵列)和测量(探针键、实验键、原始值、标准化值、p 值等)。

如果您的查询通过实验或探测进行,NoSQL 将起作用。这意味着,获取一个探针的所有值(跨所有实验)与获取一个实验的所有探针是互斥的。如果您想使用任何 NoSQL 工具(包括 Cassandra),则需要将数据存储两次。

另一方面,卷并没有太大,无法防止将其存储在单个节点上。例如,80k 实验 X 5M 探测 X 每条记录 100 字节 = 40TB,您可以通过 12x6GTB = 60TB 的 RAID6 系统来覆盖(减去 2 个磁盘以实现冗余)。

由于您可能需要一次实验或一次探测的所有值,因此另一种选择是使用平面文件。第一组是您的输入数据,第二组是您必须通过查询数据库来编译的。为了避免扩展磁盘寻道,将数据存储在物理上的两个结构中可能是成功的唯一方法。

于 2017-11-27T18:54:32.067 回答