2

有一些看起来像这样的数据:

widget:
{
    categories: ['hair', 'nails', 'dress']
    colors:     ['red', 'white']
}

需要这样查询数据:

SELECT * FROM widget_table WHERE categories == 'hair' AND colors == 'red'

在这种情况下,相等运算符categories == 'hair'实际上是在说WHERE 'hair' equals at least one of the values in the list. 使用一种我认为被称为“之字形合并连接”的算法,该操作可以在与传统相等操作相同的大 O 时间内完成。

我们正在使用的数据集包含数以千万计的这些对象。上面提供的查询需要每秒对数据库执行大约 50 次。该数据库每秒也有大约 50 次插入。由于这个要求,数据库必须在多台机器上水平扩展,这样读写操作就不必触及集群中的所有机器。我相信最好的方法是使用sharding.

据我了解,只要查询不包含针对多个字段的不等式运算符,它查询的数据就可以在多台机器上进行索引和分片。(这是 GAE 大表的规则)

我的印象是 MongoDB 将是这个用例的一个很好的候选者,但是我最近意识到 MongoDB 的分片功能的一个警告:列表字段不能用作分片键。因此,如果我想为此使用 MongoDB,我将不得不在连接到 MongoDB 的应用程序的数据层中编写一个 hack。这是我之前发布的关于使用 MongoDB 存储和查询此用例的问题:Can a list field be a shard key in MongoDB?

我之前使用 GAE 的 Big Table 实现了这些要求,据我了解,它是一个大规模分片的数据库。但是,由于 GAE 访问大表的高成本(100 万次读取或写入操作大约 1 美元?),我们已经将我们的基础架构迁移到云服务器(我们现在在 Rackspace 云服务器上,如果您不熟悉它们,他们类似于 Amazon EC2)。

我的问题是:

我们应该为此使用什么数据库?

我知道还有其他 NoSQL 数据库声称能够像 CouchDB 和 Cassandra 一样水平扩展。我认为 MongoDB 就是其中之一。我们花了几个星期将大量数据移植到 MongoDB 中,然后发现它不支持我们的主要用例之一,我感到有点无能。不想再犯这个错误。

4

1 回答 1

0

对于任何非关系(NoSQL),您必须将数据结构与数据库类型相匹配,否则它将破坏您的项目。

MongoDB 很棒,但它最擅长查询“文档”中的半结构化数据,而不是跨集合。换句话说,DocumentDB 是关于避免 JOIN 的查询,使用 MongoDB,您可以执行非惯用查询,但它们不会扩展......正如您所经历的那样。再说一次,喜欢 MongoDB,但我认为它不适合您的用例。

在您的情况下,特别是因为您说 BigTable 非常适合您的查询/数据结构类型。我建议您调查一些面向列的数据库。Cassandra 肯定值得一试。

于 2015-10-28T00:19:13.190 回答