2013-09-01 62 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