如何排序/订购数据?

时间:2011-09-29 18:50:23

标签: sql-order-by riak

我已经有过MongoDB,CouchDB,Redis,Tokyo Cabinet和其他NoSQL数据库的经验。最近我偶然发现了Riak,它对我来说非常有趣。为了开始使用它,我决定写一个小的Twitter克隆,NoSQL World中的“hello world”。要获得完全可用的克隆,有必要按时间顺序排序推文。在阅读了Riak文档之后,我发现Map-Reduce是这项工作的正确工具。在我的开发环境中它运行得很好,但是生产中的性能如何,有数百个并行查询?是否有其他的,可能更快的方法来排序数据,或者是否可以以有序的形式存储数据(如Cassandra)?

我想我找到了另一个解决这个问题的方法 - 一个简单的链表。因此,一个可能的实现可能是,每个用户都获得他/她自己的“时间线桶”,其中存储了与推文 - 数据本身的链接(推文被单独存储在“推文”桶中)。如您所知,此时间轴存储桶必须包含名为“first”的键,该键链接到最新的时间轴对象并且是列表的起点。要在时间轴中插入新推文,只需在时间轴存储桶中插入一个新项目,将此新项目的“下一个”链接设置为“第一个” - 项目,然后将新项目设置为“第一个”。

简而言之:像在链接列表中那样插入项目...

与Twitter一样,个人时间表只显示向用户显示的20条推文。要收到最后20条推文,只需要2个查询。为了加快速度,第一个查询使用Riak的链接行走能力来获取最新的20个对象,标记为“next”。最后,第二个和最后一个查询使用第一个查询计算的键来接收推文本身(使用map / reduce)。

要删除您刚刚取消关注的用户的推文,我会使用Riak 1.0的二级索引功能来接收相关的时间轴对象/推文。

2 个答案:

答案 0 :(得分:2)

在Riak中无法以重新编写部分Riak核心的方式存储有序形式的数据。数据大致以存储桶+密钥顺序存储。实际的顺序取决于您用于Riak的后端存储机制。

Riak 1.0也有一些可能对您有帮助的功能。支持二级索引以及Map Reduce操作的改进 - 特别是,它们在高度并发的场景中表现更好。

Alexander Siculars写了一篇关于Pagination with Riak的文章。它很好地概述了这个问题。 Yammer还广泛使用Riak,他们的两位工程师组织了关于Riak at Yammer的演讲。它没有涉及很多实现细节,但您可以了解他们如何设计解决方案。

结合二级索引查询和Map Reduce,可以非常轻松地解决您的问题。

答案 1 :(得分:0)

正如Jeremiah所说,不可能按排序顺序存储数据,但您仍然可以通过使用二级索引和map / reduce来返回排序结果。如上所述,问题在于您无法以排序的方式有效地限制查询。

这是一个使用范围查询列出所有键然后使用* riak_kv_mapreduce * ::

中的内置函数对它们进行排序的示例
{ok, Pid} = riakc_pb_socket:start_link("127.0.0.1", 8087),
riakc_pb_socket:mapred(Pid                                               
    , {index, colonel_riak:bucket(context), <<"$key">>, <<0>>, <<255>>}       
    , [{reduce, {modfun, riak_kv_mapreduce, reduce_sort}, none, true}])

您可以在erlang中使用lists模块中的函数或使用本机javascript排序函数。可以通过erlang中的lists:reverse/1来实现排序。