Cassandra:使用不同的值更新多行

时间:2016-12-22 17:28:10

标签: sql cassandra cql nosql

嗨我在Cassandra有类似的表:

CREATE TABLE TestTable( id text, 
        group text,
        date text,
        user text,
        dept text,
        orderby int,
        files list<text>,
        users list<text>, 
        family_memebrs list<frozen <member>>,
        PRIMARY KEY ((id)));'
CREATE INDEX on TestTable (user);
CREATE INDEX on TestTable (dept);
CREATE INDEX on TestTable (group);
CREATE INDEX on TestTable (date);
 Id    | OrderBy
:----  | :----
101    |  1
102    |  2
105    |  3

我想以相同的顺序更改以下ID 105,102,103的现有顺序。即,(105,1)(102,2)(103,3)。我是Cassandra的新手,请帮助我。我认为通过rownum和join可以在sql中使用。

1 个答案:

答案 0 :(得分:3)

  

我是Cassandra的新手

我可以说。第一个线索是你的结果的顺序。使用id作为您唯一的PRIMARY KEY(使其成为您的分区键),您的结果将永远不会像这样排序。 这个是如何排序的:

aploetz@cqlsh:stackoverflow> SELECT id,orderby,token(id) FROM testtable  ;

 id  | orderby | system.token(id)
-----+---------+---------------------
 102 |       2 | -963541259029995480
 105 |       3 | 2376737131193407616
 101 |       1 | 4965004472028601333

(3 rows)

未绑定查询始终返回按分区键的哈希标记值排序的结果。我已在您的分区键(token())上运行id函数来显示此内容。

  

我想以相同的顺序更改以下ID 105,102,103的现有顺序。即,(105,1)(102,2)(103,3)。

如果你需要做的就是更改orderby列中的值,那很容易:

aploetz@cqlsh:stackoverflow> INSERT INTO testtable(id,orderby) VALUES ('101',3);
aploetz@cqlsh:stackoverflow> INSERT INTO testtable(id,orderby) VALUES ('102',2);
aploetz@cqlsh:stackoverflow> INSERT INTO testtable(id,orderby) VALUES ('105',1);
aploetz@cqlsh:stackoverflow> SELECT id,orderby,token(id) FROM testtable  ;

 id  | orderby | system.token(id)
-----+---------+---------------------
 102 |       2 | -963541259029995480
 105 |       1 | 2376737131193407616
 101 |       3 | 4965004472028601333

(3 rows)

由于Cassandra PRIMARY KEY是唯一的,只需为该键插入一个新的非键列值即会更改orderby

现在,如果您希望能够按orderby列对结果进行排序,则完全是另一个问题,并且无法使用您当前的模型解决。

如果这是您真正想要做的事情,那么您需要一个具有不同PRIMARY KEY定义的新表。因此,我将创建相同的表格,其中包含两项更改:我将其命名为testtable_by_group,并且我将使用PRIMARY KEY (group,orderby,id))的复合PRIMARY KEY。现在我可以查询特定的组&#34; group1&#34;并查看结果排序。

aploetz@cqlsh:stackoverflow> CREATE TABLE testtable_by_group (group text,id text,orderby int,PRIMARY KEY (group,orderby,id));
aploetz@cqlsh:stackoverflow> INSERT INTO testtable_by_group(group,id,orderby) VALUES ('group1','101',3);
aploetz@cqlsh:stackoverflow> INSERT INTO testtable_by_group(group,id,orderby) VALUES ('group1','102',2);
aploetz@cqlsh:stackoverflow> INSERT INTO testtable_by_group(group,id,orderby) VALUES ('group1','105',1);
aploetz@cqlsh:stackoverflow> SELECT group,id,orderby,token(group) FROM testtable_by_group WHERE group='group1';

 group  | id  | orderby | system.token(group)
--------+-----+---------+----------------------
 group1 | 105 |       1 | -2413872665919611707
 group1 | 102 |       2 | -2413872665919611707
 group1 | 101 |       3 | -2413872665919611707

(3 rows)

通过这种方式,group是新的分区键。 orderby是第一个群集密钥,因此group中的行会自动按其排序。如果任何两行具有相同的idorderby就会确保唯一性。

请注意,我在结果集中保留了token()函数,但是我在新的分区键(group)上运行了它。如您所见,group1的键被散列为所有3行的相同标记,这意味着在多节点环境中,所有3行将一起存储。这可以创建一个热点&#34;在您的群集中,某些节点的数据比其他节点多。这就是为什么一个好的PRIMARY KEY定义可以确保查询满意度数据分布的原因。

前段时间我为DataStax撰写了一篇关于此主题的文章。给它一个阅读,它应该帮助你:http://www.datastax.com/dev/blog/we-shall-have-order