在Cassandra,我不知道怎么做ORDER BY

时间:2016-12-20 02:09:26

标签: cassandra spring-data

我准备了下表“keyspaceB.memobox”

DROP TABLE IF EXISTS keyspaceB.memobox;
CREATE TABLE IF NOT EXISTS keyspaceB.memobox (
    pkey1 text,
    pkey2 text,
    id timeuuid,
    name text,
    memo text,
    date timestamp,
    PRIMARY KEY ((pkey1, pkey2),id,name)
) WITH CLUSTERING ORDER BY (id DESC,name DESC);

我注册了以下数据。

INSERT INTO memobox (pkey1,pkey2,id,name,memo,date) VALUES ('a','b',now(),'tanaka','greet message1','2016-12-13');
INSERT INTO memobox (pkey1,pkey2,id,name,memo,date) VALUES ('a','b',now(),'yamamoto','greet message2','2016-12-13');

以下内容将成功

SELECT * FROM memobox where pkey1='a' and pkey2='b' ORDER BY id;

但是,以下内容将失败。我想问你的教授有什么问题。

SELECT * FROM memobox where pkey1='a' and pkey2='b' ORDER BY name;

■错误

cqlsh:keyspaceb> SELECT * FROM memobox where pkey1='a' and pkey2='b' ORDER BY name;
InvalidRequest: code=2200 [Invalid query] message="Order by currently only support the ordering of columns following their declared order in the PRIMARY KEY"
cqlsh:keyspaceb>

1 个答案:

答案 0 :(得分:2)

cassandra,分区键和群集键中有两种不同类型的键。 分区键确定数据存储在哪个节点,而clusterning键确定数据存储在该分区(节点)中的顺序。

在您的情况下,分区键为pkey1pkey2。并且群集密钥为idname

因此,分区中的数据将根据id然后name进行存储。

例如,如果我们有以下数据

id |name 
1  | abc
1  | xyz
2  | aaa

在这种情况下,首先存储id为1的行,如果两行具有相同的id,则命令由name列决定。

所以当你查询这样的数据时

SELECT * FROM memobox where pkey1='a' and pkey2='b' ORDER BY id;

cassandra使用pkey1和pkey2(也就是分区键)找到partitoin,然后只返回数据在磁盘上的存储方式。

然而在第二种情况下

SELECT * FROM memobox where pkey1='a' and pkey2='b' ORDER BY name;

因为数据不是按名称单独排序的(它首先按id排序,然后按名称排序)。 cassandra不能盲目地返回结果,它必须做更多的事情才能正确地对结果进行排序。因此,由于性能原因,这是不允许的。

这就是为什么在order by子句中你必须按创建表(id和then name)时指定它们的顺序指定聚类列。

这是@aaron的另一个答案 Where and Order By Clauses in Cassandra CQL

  

Cassandra通过使用群集键进行排序来实现性能   您的数据在磁盘上,因此只返回单个行中的有序行   读(没有随机读)。这就是您必须采用基于查询的原因   建模方法(通常将您的数据复制到多个查询中   表)与Cassandra。提前了解您的疑问,并建立   你的桌子为他们服务。