2014-08-31 44 views
3

我将数据存储在一个Cassandra 2.0.10表中。有一列(名为score),整数类型,可以采取任何值。我需要编写一个后台作业,将值分配给另一列rank,给出值为1的分数字段中值最高的行,值为2的分数字段,等等。具有最小值score的行必须获得分配给rank的总行数。这是目前在定制列表定义为如何从卡桑德拉表建立排序列表?

CREATE TABLE players 
    (user int, rank int, score int, details blob, PRIMARY KEY(user)) 

赌注它像PostgreSQL的,我会做一些喜欢使用增加了一个值

select id, rank from players order by score desc offset A limit 100; 

和这样迭代数据库的大小100.页在一次查询中会给我排名前100的玩家,第二次排名前100到200等等。然后我可以通过ID,逐个或批量发布更新声明。

当我尝试在Cassandra CQL中做同样的事情时,发现许多所需功能不受支持(没有顺序,没有偏移,没有明确的方式来访问所有行)。我试图建立分数列的索引,但这没有帮助。

这个等级分配是一个帮手工作。迭代需要几天甚至几周是没有问题的。可以稍微不一致,因为在作业运行时分数可能会发生变化。这不是应用程序的主要功能。主要功能不使用范围查询,Cassandra可以在那里很好地工作。

是否有可能以某种方式将Java和CQL结合起来使用,或者限制足够严重我需要使用不同的数据库引擎?

+0

请编辑您的帖子,添加表格说明。 – 2014-09-01 07:07:58

+0

在CQL中添加了表格声明。 – h22 2014-09-01 17:55:03

回答

1

根据我的经验,卡桑德拉不适合这种类型的任务。你当然可以做到这一点,但解决方案不会简单而有效。遍历一个表中的所有行来更新行列没有问题,但是按照行列顺序迭代所有行是有问题的。你可以保留两张牌:

players(id,rank)and rank_to_id(rank,id_list)。然后,你应该使用查询第二页:

SELECT * FROM rank_to_id其中排名> 100极限100

你的排名出让方的责任将是正确更新两个表时排名正在发生变化。基本上由此你将实现PostgreSQL开箱即用的简单数据库索引。

另外我建议你看看Redis DB。它具有Sorted Set这样一个很好的数据类型,它几乎可以实现你所需要的:http://redis.io/commands#sorted_set。但是,这取决于您拥有的数据量。 Redis是内存数据库。

PostgreSQL也可能是一个很好的解决方案。你为什么不想用它?