【问题标题】:Cassandra: how to read data from multiple tableCassandra:如何从多个表中读取数据
【发布时间】:2013-04-09 17:59:35
【问题描述】:

我正在使用 hector 在 java 中访问 c​​assandra。我有四个表:users、cmets、user_like、user_recommend。 user_like 和 user_recommend 表有一个计数器列。现在我想根据用户 ID 一起访问所有四个表中的数据。我该怎么做?我应该从所有表中单独获取给定的 userId 数据,还是有什么方法可以一次性获取?

【问题讨论】:

    标签: cassandra hector


    【解决方案1】:

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

    如果您想一口气阅读所有内容,请考虑将所有内容放在一个列族中,或者更好地放在一行中。

    我会这样做:

    现在你有:

    CF“cmets”
    "user1" => //行
    column "name1" = "value1" //列

    CF "user_like" "user1" => //行 column "name2" = "value2" //列

    CF“用户推荐”
    "user1" => //行
    column "name3" = "value3" //列

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

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

    CF“用户”
    ."user1_cmets" => //行
    ...column "name1" = "value1" //column
    ."user1_likes" => //行
    ...column "name2" = "value2" //列
    ."user1_recommends" => //行
    ...column "name3" = "value3" //列

    这要好得多,但仍然不是最理想的。您可以使用 multi_get 查询获得所有信息。这些查询速度较慢,因为它们可能需要等待集群中的许多节点才能返回(如果它们非常相似,不同的键可能会落入不同的节点事件中)

    最佳:所有内容都在一行中。

    CF“用户”
    ."user1" => //行
    ...column "cmets:name1" = "value1" //column
    ...column "likes:name2" = "value2" //column
    ...column "recommends:name3" = "value3" //column

    您可以通过读取一行来获取所有内容。如果您只想分别获取 cmets、likes 或 recmets,您可以使用范围查询来完成。由于所有内容都在一行中,因此您的查询往往会快得多。 Cassandra 可以很好地处理非常宽的行,因此您不必担心这些。

    cassy 的一个很好的哲学是“如果你一起阅读它(同时)然后将它保存在一起(在同一个位置)”。

    编辑:在没有计数器的情况下做计数器的技巧。

    Cassandra 一直非常擅长编写新值(事实上,这是它在后台所做的 100%)。再加上计算一行或该行范围内的列非常快。所以我想出了一种方法来做“计数器”,可以用来防止重复计数。注意:这仅适用于单一增量(+1 ...喜欢点赞、点赞等等)。

    您需要做的就是在代表该计数器的行中写入一个新列: 如果要允许重复,请将列名设置为 timeUuid 或时间戳。否则将其设为他点赞的消息的 id(这样,如果他点赞两次,仍然算作点赞)。

    现在您有两种解决方案:触发多个查询以计算列数或一次读取所有内容并使用 java.util.Collection.size() 进行计数。

    此解决方案确实使用了 cassandra 的优点,但它可能并不适合所有人,尤其是如果您想避免非常宽的行。知道 Cassandra 可以处理非常宽的行,但您在应用中用于计数的 Collection 可能会出现内存问题。

    你可能会得到这样的结果:

    CF“用户”
    ."user1" =>
    ...列“评论:名称1”=“值1”
    ...列“评论:名称2”=“值2”
    ...column "likes: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”
    ...column "recommend:7ba30e15-2b76-4aaa-b2d0-f8419a80a769" = "1" // 推荐商品的uuid
    ...列“推荐:603879cc-d7b0-4767-ad27-e5dd4aa34f62”=“1”

    【讨论】:

    • 感谢您的信息。但这里的第一件事是“推荐”,“喜欢”是一个计数器,所以它不能在同一个 CF 中。其次,将 cmets 放在同一个 CF 中 ..我认为最好放在单独的 CF 中,它会不那么复杂,我认为这是一种普遍的做法,你说什么?如果我没记错的话,没有人会将用户信息和 cmets 保存在同一个 CF 中。
    • 您仍然可以将所有计数器放在一张桌子上。以及所有不是另一个计数器的东西。但是你拥有的桌子越少越好。对于 N 个表,您最多可以有 N 个查询。我将编辑我的消息,以获得我想出的用于单一增量的技巧。
    猜你喜欢
    • 1970-01-01
    • 2020-12-27
    • 2014-03-26
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 2018-02-16
    • 2020-01-23
    • 2015-04-29
    相关资源
    最近更新 更多