2013-09-01 65 views
4

我使用Cassandra 1.2.7和使用CQL3的官方Java驅動程序。Cassandra CQL3從複合主鍵表中選擇行鍵

假設由

CREATE TABLE foo ( 
    row int, 
    column int, 
    txt text, 
    PRIMARY KEY (row, column) 
); 

創建一個表然後我想預製棒SELECT DISTINCT row FROM foo

至於我的理解相當於它應該可以Cassandra的數據模型中有效地執行這個查詢(給定複合主鍵的實現方式),因爲它只會查詢「原始」表。

我搜索了CQL文檔,但沒有找到任何選項來做到這一點。

我的備份計劃是創建一個單獨的表 - 像

CREATE TABLE foo_rows (
    row int, 
    PRIMARY KEY (row) 
); 

但這需要保持兩個同步的麻煩 - 寫foo_rows在FOO任何寫操作(也有性能損失)。

那麼有沒有什麼辦法來查詢不同的行(分區)鍵?

回答

4

根據documentation,從CQL版本3.11,cassandra瞭解DISTINCT修飾符。 所以你現在可以寫

SELECT DISTINCT row FROM foo 
0

@edofic

分區行鍵被用作唯一的索引中存儲引擎來區分不同的行,以便通過性質,行鍵總是不同。你不需要把DISTINCT SELECT子句中

INSERT INTO foo(row,column,txt) VALUES (1,1,'1-1'); 
INSERT INTO foo(row,column,txt) VALUES (2,1,'2-1'); 
INSERT INTO foo(row,column,txt) VALUES (1,2,'1-2'); 

然後

SELECT row FROM foo 

將返回值2:1和2

下面的事情是如何堅持在卡桑德拉

+ ---------- + ------------------- + ------------ ------ +
|行鍵| column1/value | column2/value |
+ ---------- + ------------------- + ---------------- - +
|                     |                     1/'1'                   |                     2/'2'               |
|                     |                     1/'1'                   |                                               |
+ ---------- + ------------------- + ---------------- - +

+1

這裏就是'選擇行FROM FOO;'我回報(與你的插入) cqlsh:測試> SELECT列FROM FOO; ' 行 ----- ' 這是我要求首先這個問題的原因(我的理解是如何與複合鍵的表持續) – edofic

+0

@edofic沒有你找到除「DISTINCT」關鍵字之外的解決方案? – FelikZ

+1

@FelikZ不,「DISTINCT」正是我想要的 – edofic

7

我會給你不好的方法來做到這一點。如果將這些行:

insert into foo (row,column,txt) values (1,1,'First Insert'); 
insert into foo (row,column,txt) values (1,2,'Second Insert'); 
insert into foo (row,column,txt) values (2,1,'First Insert'); 
insert into foo (row,column,txt) values (2,2,'Second Insert'); 

做一個

'select row from foo;' 

會給你以下幾點:

row 
----- 
    1 
    1 
    2 
    2 

不顯着,因爲它顯示的行和列的所有可能的組合。要查詢得到一個行值,你可以添加一列值:

select row from foo where column = 1; 

但隨後你會得到這樣的警告:

Bad Request: Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING 

確定。然後與此:

select row from foo where column = 1 ALLOW FILTERING; 

row 
----- 
    1 
    2 

很好。我想要的。不過,我們不要忽視那個警告。如果你只有很少的行數,比如說10000,那麼這將在性能上沒有太大的影響。現在如果我有10億呢?根據節點數量和複製因素,您的性能將受到嚴重影響。首先,查詢必須掃描表中的每個可能的行(讀全表掃描),然後過濾結果集的唯一值。在某些情況下,這個查詢將會超時。鑑於此,可能不是你想要的。

您提到您擔心插入到多個表中時性能受到影響。多個表格插入是完美有效的數據建模技術。卡桑德拉可以做大量的寫作。至於同步的痛苦,我不知道你確切的應用,但我可以給一般的提示。

如果您需要獨特的掃描,您需要考慮分區列。這就是我們所說的索引或查詢表。在任何Cassandra數據模型中要考慮的重要事情是應用程序查詢。如果我使用IP地址作爲行,我可能會創建類似這樣的內容來掃描我所有的IP地址。

CREATE TABLE ip_addresses (
first_quad int, 
last_quads ascii, 
PRIMARY KEY (first_quad, last_quads) 
); 

現在,插入一些行我192.xxx地址空間:

insert into ip_addresses (first_quad,last_quads) VALUES (192,'000000001'); 
insert into ip_addresses (first_quad,last_quads) VALUES (192,'000000002'); 
insert into ip_addresses (first_quad,last_quads) VALUES (192,'000001001'); 
insert into ip_addresses (first_quad,last_quads) VALUES (192,'000001255'); 

要獲得在192空間的不同行,我這樣做:

SELECT * FROM ip_addresses WHERE first_quad = 192; 

first_quad | last_quads 
------------+------------ 
     192 | 000000001 
     192 | 000000002 
     192 | 000001001 
     192 | 000001255 

要得到每一個地址,你只需要遍歷0-255的每一個可能的行鍵。在我的例子中,我希望應用程序要求特定的範圍來保持性能。你的應用程序可能有不同的需求,但希望你能看到這裏的模式。

+0

好戲。但我的問題是列不會是異構的 - 我不能確定在所有行中都有一列'1'。我有點想從你的IP例子中做出相反的事情。假設你也有第一個8和10的行。然後我想寫一個返回的查詢(8,10,192)。但我不知道存儲了哪些IP。 – edofic