如何使用CQL3引入一系列复合列?
请考虑以下事项:
CREATE TABLE Stuff (
a int,
b text,
c text,
d text,
PRIMARY KEY (a,b,c)
);
在Cassandra中,有效的做法是创建一个具有整数行(值为a)的ColumnFamily,以及由b和c的值以及文字字符串“d”组成的CompositeColumns。当然,这一切都被CQL3所掩盖,因此我们认为我们正在插入单独的数据库行......但我离题了。
考虑以下一组输入:
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','P','whatever0');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','Q','whatever1');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','R','whatever2');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','S','whatever3');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','T','whatever4');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','P','whatever5');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','Q','whatever6');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','R','whatever7');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','S','whatever8');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','T','whatever9');
在我目前的用例中,我想一次读取Stuff的所有值,n
值。我该怎么做呢?以下是我目前使用n=4
:
SELECT * FROM Stuff WHERE a=1 LIMIT 4;
正如我所料,我得到了:
a | b | c | d
---+---+---+-----------
1 | A | P | whatever0
1 | A | Q | whatever1
1 | A | R | whatever2
1 | A | S | whatever3
我遇到的麻烦是如何获得接下来的4?这是我的尝试:
SELECT * FROM Stuff WHERE a=1 AND b='A' AND c>'S' LIMIT 4;
这不起作用,因为我们将b限制为等于'A' - 这是合理的事情!但我在CQL3语法中没有发现任何东西,它允许我继续迭代。我希望我能做一些像:
SELECT * FROM Stuff WHERE a=1 AND {b,c} > {'A','S'} LIMIT 4;
如何实现我想要的结果。也就是说,我如何让CQL3返回:
a | b | c | d
---+---+---+-----------
1 | A | T | whatever0
1 | B | P | whatever1
1 | B | Q | whatever2
1 | B | R | whatever3
答案 0 :(得分:5)
自动分页已完成https://issues.apache.org/jira/browse/CASSANDRA-4415,已发布到Cassandra 2.0.1
答案 1 :(得分:4)
通过CQL3文档阅读后,我找不到达到预期效果的方法。
但是,您可以使用一系列CQL查询伪造所需的效果。考虑到我想一次分页以上模型4中的项目。获得前4个很容易:
SELECT * FROM a = 1 LIMIT 4;
但是没有办法在单个查询中获得下一个4。但我可以分段做。上述查询中的最后一项是
a | b | c | d
---+---+---+-----------
1 | A | S | whatever3
所以我可以发出一个查询从这里开始并获取所有内容,直到b
的下一个值:
SELECT * FROM a = 1 WHERE b ='A'和c>'S'LIMIT 4;
在这种情况下,我将获得一个CQL3行:
a | b | c | d
---+---+---+-----------
1 | A | T | whatever4
(现在,如果我有4行,我会达到极限,然后我会再次使用该组的最后一个元素重新开始。但是现在我只有一行。)所以,要得到其余的我从那个点迭代并获得剩余的3行:
SELECT * FROM a = 1 WHERE b > 'A' LIMIT 3;
我继续使用相同的算法,直到我尽可能地逐步扫描。
在上面的示例中,PRIMARY KEY由3个元素组成,这意味着在Cassandra的CQL下,列名称是2个元素的CompositeColumns(......基本上很好,但差别在这里并不重要)。因为CompositeColumns有2个元素,所以我必须在这里进行2次查询。通常,如果PRIMARY KEY是n
个元素,那么你将不得不进行n-1
个查询来伪造CQL表的扫描(a.k.a Cassandra行)。
更新:确实,CQL3没有服务器端游标,(参见“CQL3分页”部分here),如果你想伪造它,你必须使用上述内容(请仔细阅读该链接,以便查看帖子作者详细阐述的基本想法。
但是,有关服务器端游标的JIRA issue将在Cassandra 2中可用,并且已存在于Cassandra 2 Beta中。
还有一个相关的JIRA issue可以让我更容易实现客户端游标,正如我在上面所暗示的那样。但它没有得到解决。
Update2:JIRA issue现已修复。
您现在可以使用元组/向量语法WHERE(c1,c2)>进行查询。 (1,0)
答案 2 :(得分:0)
你要做的就是在卡桑德拉获得分页内容。 CQL3不支持此功能。 您应该创建一个适合比较的列,即小于,大于操作的列,此列应形成递增/递减序列。实际上,正如jorgebg上面提到的那样,b + c的连接符合这一点。
答案 3 :(得分:-1)
select * from stuff where a = 1 and (b,c) > ('A','S') limit 4;