【问题标题】:Order by on mutable columns in cassandra在 cassandra 中的可变列上排序
【发布时间】:2016-04-27 10:47:15
【问题描述】:

我有一张表,其架构如下:

create table xx(
 bucket_id int,
 like_count int,
 photo_id int,
 username text,
 PRIMARY KEY(bucket_id,like_count,photo_id)
) WITH CLUSTERING ORDER BY (like_count DESC)

在这里我可以按like_count的降序获取所有记录。但是我需要在我的应用程序中的某个时间点更新 like_count,因为它是主键的一部分,所以我无法这样做。

如果我从主键中删除它,我无法获得基于 like_count 的排序结果。在 cassandra 中解决这个问题的正确方法是什么?

【问题讨论】:

    标签: cassandra


    【解决方案1】:

    恐怕 Cassandra 不适合处理可变订单。 (请考虑使用 Redis 排序集) 话虽如此,您实际上可以使用类似 CAS 的语义(比较和设置)和轻量级事务来实现这一点,这将使您的更新速度慢 20 倍左右。

    您还需要一个附加表,用于查找每个 bucket_id/photo_id 的当前 like_count。

    create table yy (
      bucket_id int,
      photo_id int,
      like_count int,
      PRIMARY KEY((bucket_id,photo_id))
    )
    

    然后从 xx 执行轻量级事务删除,然后(如果成功)重新插入 xx 并更新到 yy: 一些伪代码:

    //CAS loop (supposedly in a function of args: bucket_id, photo_id, username, new_score)
    for (;;) {
    
      //read current score (the assumption here is that the bucket_id/photo_id entry already exists in both xx and yy)
      ResultSet rs1 = select like_count from yy where bucket_id = ? and photo_id = ?
      int old_score = rs1.one().getInt(0)
    
      //same score don't do anything
      if (new_score == old_score) break;
    
      //attempt to delete using light-weight transaction (note usage of IF EXISTS)
      ResultSet r2 = delete from xx where bucket_id = ? and photo_id = ? and like_count = old_score IF EXISTS
      if (rs2.one().getBool(0)) {
    
        //if delete was successful, reinsert with the new score
        insert bucket_id, photo_id, photo_id, username, like_count into xx values (?, ?, ?, new_score)
    
        //update lookup table
        update yy set like_count = new_score where bucket_id = ? and photo_id = ?
    
        //we are done!
        break;
      }
    
      //delete was not successful, someone already updated the score
      //try again in a next CAS iteration
    }
    

    【讨论】:

      【解决方案2】:

      PRIMARY KEY 定义中删除like_count 并对应用程序执行排序。如果这种更改很少发生在几个键上,您可以考虑删除整个条目并用更新的值重写它,但我不推荐这种解决方案。

      HTH, 卡罗

      【讨论】:

      • 该表有大约 10-15k 条记录,它也必须支持分页。使用您的解决方案,应用程序必须对每个页面的所有记录进行排序。
      • 很抱歉在没有评论的情况下否决了这个,但我认为你的回答没有给出一般的解决方案。
      • 感谢您的解释-恕我直言,应该为误导/错误的答案保留反对票,但事实并非如此。如果您认为它不能提供通用解决方案,请不要投票
      猜你喜欢
      • 2016-04-10
      • 2021-02-28
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-14
      • 2016-07-18
      相关资源
      最近更新 更多