2016-12-20 65 views
0

我下表“keyspaceB.memobox”在卡桑德拉,我不知道该怎么办ORDER BY

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> 

回答

2

有两种不同类型的卡珊德拉,分区键和聚集键的键。 分区键确定数据存储在哪个节点,而聚簇键确定数据存储在该分区(节点)中的顺序。

在你的情况下,分区键是pkey1pkey2。集群密钥为idname

因此分区中的数据将基于id然后name存储。

e.g如果我们有如下的数据

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

在这种情况下,ID为1的行首先被存储,此外,如果两行有相同的ID,则顺序由名字列决定。

所以,当你查询数据这样

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

卡桑德拉发现使用pkey1和pkey2的partitoin(又名分区键),然后就返回它是如何存储在磁盘上的数据。

然而在第二种情况下

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

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

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

这是从另外一个答案通过@aaron Where and Order By Clauses in Cassandra CQL

卡桑德拉使用聚类键 您的磁盘上的数据进行排序,从而只在一个 读返回下令行达到性能(没有随机读取)。这就是为什么您必须采用基于查询的 建模方法(通常将您的数据复制到多个查询表 表)与Cassandra。提前了解您的问题,并建立 您的表格为他们服务。

+0

感谢您的详细解答!我很感激。这非常有帮助。 –