2017-04-06 63 views
1

我有一个数据建模问题的情况下,数据需要通过可以修改的键排序。 所以,说我们有一个用户表Cassandra排序和一个不断变化的集群密钥

{ 
    dept_id text, 
    user_id text, 
    user_name text, 
    mod_date timestamp 
    PRIMARY KEY (dept_id,user_id) 
} 

现在我可以查询卡桑德拉由dept_id为获得所有用户。

如果我想查询获取部门中的所有用户,按mod_date排序,该怎么办?

所以,一个办法是

{ 
    dept_id text, 
    mod_date timestamp, 
    user_id text, 
    user_name text, 
    PRIMARY KEY (dept_id, mod_date,user_id) 
} 

但是,mod_date的每一次变化的用户名进行更新。所以它不能成为集群密钥的一部分。

尝试1:
不要更新行,而是为每一个更新创造新的纪录。

所以,说为用户foo记录是像下面 {'dept_id1',TimeStamp1','user_id1','foo'} ,然后更名为“巴”,然后到“巴兹”。 在这种情况下,我们添加另一行表,所以它看起来像

{'dept_id1',TimeStamp3','user_id1','baz'} 
{'dept_id1',TimeStamp2','user_id1','bar'} 
{'dept_id1',TimeStamp1','user_id1','foo'} 

现在,我们可以得到所有用户在一个部门,由mod_date排序,但它提出了一个不同的问题。

返回的数据被复制

尝试2: 添加另一列识别很像一个链表

{ 
    dept_id text, 
    mod_date timestamp, 
    user_id text, 
    user_name text, 
    next_record text 
    PRIMARY KEY (dept_id,mod_date,user_id) 
} 

每次更新发生它的头记录添加一行并还增加了新的记录的PK。

{'dept_id1',TimeStamp3','user_id1','baz','HEAD'} 
{'dept_id1',TimeStamp2','user_id1','bar','dept_id1#TimeStamp3'} 
{'dept_id1',TimeStamp1','user_id1','foo','dept_id1#TimeStamp2'} 

并且还将一个二级索引添加到'next_record'列。

现在我可以支持其中的dept_id =从用户获得所有用户的部门,由mod_date排序由

SELECT * ':部门' AND next_record = 'HEAD' 为了 通过mod_date。

但它看起来相当复杂的解决方案,也许我失去了一些东西,一个简单的解决方案..

另一种选择是删除和插入,但对高频率的变化,我认为卡桑德拉有墓碑的问题。

建议/意见反馈。 谢谢!

+0

您使用哪个cassandra版本?另一件事你的主键是'dept_id,user_id,mod_date',所以你的数据按照user_id排序,然后mod_date在dept_id下排序? –

+0

谢谢。我更新了问题以反映所需的排序顺序。 user_id只是噪音问题。我希望希望问题的意图是明确的。我正在使用Cassandra 2.2.x – factotum

回答

0

正如我所看到的,最简单的方法是对应用程序(客户端代码)端的用户进行排序。您使用dept作为分区键,这意味着一个部门中的所有用户都可以处理一个cassandra节点,因此一个部门中没有多个用户,并且可以在应用程序端快速排序此用户。