在cassandra上按可变列排序

时间:2015-03-23 16:32:16

标签: cassandra

我有一个包含以下架构的表格:

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中解决这个问题的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

我担心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并更新为yy,从xx执行轻量级事务删除(如果成功): 一些伪代码:

//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
}

答案 1 :(得分:-1)

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

HTH, 卡罗

相关问题