2016-12-20 64 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

感謝您的詳細解答!我很感激。這非常有幫助。 –