Cassandra:如何从多个表中读取数据

时间:2013-04-08 07:21:40

标签: cassandra hector

我正在使用hector来访问java中的cassandra。我有四个表:用户,评论,user_like,user_recommend。 user_like和user_recommend表有一个计数器列。现在我想根据用户ID一起访问所有四个表中的数据。我怎么能这样做?我应该从所有表中单独获取给定的userId数据,还是有任何方法可以一次性获取它?

1 个答案:

答案 0 :(得分:1)

不幸的是,查询绑定到列族。因此,每个列族都需要一个查询。

如果你想阅读一篇文章中的所有内容,请考虑将所有内容放在一个列族中,或者甚至更好地放在一行中。

我将如何做到这一点:

现在你有:

CF"评论"
 "用户1" => //行
   专栏" name1" =" value1" //柱

CF" user_like"  "用户1" => //行    专栏" name2" =" value2" //列

CF" user_recommend"
 "用户1" => //行
   专栏" name3" =" value3" //列

这需要3个查询,因为您有3个列族。

一个列族中的所有内容都是:

CF"用户"
" user1_comments" => //行
...列" name1" =" value1" //列
" user1_likes" => //行
...列" name2" =" value2" //列
" user1_recommends" => //行
...列" name3" =" value3" //列

这样做更好但​​仍然不是最佳的。你可以使用multi_get查询来获取所有内容。这些查询较慢,因为它们可能需要在群集中的许多节点上等待返回(如果它们非常相似,则不同的键可以落入不同的节点事件中)

最佳:一行中的所有内容。

CF"用户"
"用户1" => //行
...列"评论:name1" =" value1" //列
...列"喜欢:name2" =" value2" //列
...列"建议:name3" =" value3" //列

您可以通过一行读取所有内容。如果您只想单独获得评论,喜欢或推荐,可以使用范围查询。由于所有内容都在一行中,因此您的查询速度会快得多。 Cassandra可以很好地处理非常宽的行,所以你不必担心这些。

cassy的良好哲学是"如果你一起阅读(同时),那么将它们保存在一起(在同一地点)"。

编辑:执行没有计数器的计数器。

Cassandra非常擅长编写新的值(事实上,这是它在后台执行的操作的100%)。另外,计算行中或该行范围内的列非常快。所以我想出了一个方法来做" counter"可以用来防止重复计数。注意:这仅适用于单位增量(+1 ... liks like,upvotes和whatnot)。

您需要做的就是在表示该计数器的行中写一个新列: 如果要允许重复,请将列名称设为timeUuid或时间戳。 Otherwize使它成为他喜欢的消息的id(这样,如果他点击两次,它仍然算作一个像)。

现在你有两个解决方案:使用java.util.Collection.size()来激活多个查询来计算列或读取一个读取和计数中的所有内容。

这个解决方案确实使用了cassandra的优点,但它可能不适合所有人,特别是如果你想避免非常宽的行。知道Cassandra可以处理非常宽的行,但是您可能会在应用程序中使用Collection来计算内存问题。

你最终会得到类似的东西:

CF"用户"
"用户1" =>
...列"评论:name1" =" value1"
...列"评论:name2" =" value2"
...列"喜欢:43f54880-a0fb-11e2-aafa-f1dce92b7e5b" =" 1" //时间uuids这里 ...列"喜欢:43f54881-a0fb-11e2-aafa-f1dce92b7e5b" =" 1"
...列"喜欢:43f54882-a0fb-11e2-aafa-f1dce92b7e5b" =" 1"
...列"喜欢:43f54883-a0fb-11e2-aafa-f1dce92b7e5b" =" 1"
...列"推荐:7ba30e15-2b76-4aaa-b2d0-f8419a80a769" =" 1" //建议项目的uuid
...列"推荐:603879cc-d7b0-4767-ad27-e5dd4aa34f62" =" 1"