有一些看起来像这样的数据:
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 中,然后发现它不支持我们的主要用例之一,我感到有点无能。不想再犯这个错误。