gpt4 book ai didi

cql - 如何在cassandra中构建范围查询?

转载 作者:行者123 更新时间:2023-12-04 06:02:30 41 4
gpt4 key购买 nike

CREATE TABLE users ( 
userID uuid,
firstname text,
lastname text,
state text,
zip int,
age int,
PRIMARY KEY (userID)
);

我想构建以下查询:
select * from users where age between 30 and 40

select * from users where state in "AZ" AND "WA"

我知道我还需要两个表来做这个查询,但我不知道应该如何?

编辑

从卡洛的评论中,我认为这是唯一的可能性
CREATE TABLE users ( 
userID uuid,
firstname text,
lastname text,
state text,
zip int,
age int,
PRIMARY KEY (age,zip,userID)
);

现在选择年龄在 15 到 30 岁之间的用户。这是唯一的可能性:
select * from users where age IN (15,16,17,....30)

但是,不建议在此处使用 IN 运算符,并且是反模式的。

如何根据年龄创建二级索引?
CREATE index users_age ON users(age)

这有帮助吗?

谢谢

最佳答案

范围查询是一个棘手的问题。
执行真正的范围查询的方法是使用复合主键,在聚类部分制作范围。由于范围在聚类部分,您无法执行您编写的查询:您至少需要对整个分区键具有相同的条件 .
让我们看一个例子:

CREATE TABLE users (
mainland text,
state text,
uid int,
name text,
zip int,
PRIMARY KEY ((mainland), state, uid)
)

uid 现在是一个 int 只是为了使测试更容易
insert into users (mainland, state, uid, name, zip) VALUES ( 'northamerica', 'washington', 1, 'john', 98100);
insert into users (mainland, state, uid, name, zip) VALUES ( 'northamerica', 'texas', 2, 'lukas', 75000);
insert into users (mainland, state, uid, name, zip) VALUES ( 'northamerica', 'delaware', 3, 'henry', 19904);
insert into users (mainland, state, uid, name, zip) VALUES ( 'northamerica', 'delaware', 4, 'dawson', 19910);
insert into users (mainland, state, uid, name, zip) VALUES ( 'centraleurope', 'italy', 5, 'fabio', 20150);
insert into users (mainland, state, uid, name, zip) VALUES ( 'southamerica', 'argentina', 6, 'alex', 10840);

现在查询可以执行您需要的操作:
 select * from users where mainland = 'northamerica' and state > 'ca' and state < 'ny';

输出
 mainland    | state    | uid | name   | zip
-------------+----------+-----+--------+-------
northamerica | delaware | 3 | henry | 19904
northamerica | delaware | 4 | dawson | 19910

如果您将 int (age, zipcode) 作为集群键的第一列,您可以执行相同的查询比较整数。

保重 :大多数人在看到这种情况时开始想“好吧,我可以放置一个始终相同的假分区键,然后我可以执行范围查询”。这是一个巨大的错误,分区键负责跨节点的数据分发。设置修复分区键意味着所有数据都将在同一个节点(及其副本)中完成。

将世界区域划分为 15/20 区域(为了拥有 15/20 分区键)是有的,但还不够,只是为了创建一个有效的示例。

编辑:由于问题的编辑

我没有说这是唯一的可能性;如果您找不到有效的方法来对您的 进行分区用户 并且需要执行这种查询,这是一种可能性,而不是唯一一种。 范围查询应该在集群键部分 上执行. AGE 作为分区键的一个弱点是您无法对其执行 UPDATE,任何时候您需要更新用户的年龄,您都必须执行删除和插入操作(另一种可能是写入birth_year/birth_date 而不是年龄,然后计算客户端)

回答你关于添加二级索引的问题:实际上二级索引上的查询不支持 IN 运算符。从 CQL 消息看来他们很快就会开发它

Bad Request: IN predicates on non-primary-key columns (xxx) is not yet supported



但是,即使二级索引支持 IN 运算符,您的查询也不会从
select * from users where age IN (15,16,17,....30)

只是为了澄清我的概念:任何没有“干净”和“就绪”解决方案的东西都需要用户努力以满足其需求的方式对数据进行建模。举个例子(我不是说这是一个好的解决方案:我不会使用它)
CREATE TABLE users (
years_range text,
age int,
uid int,
PRIMARY KEY ((years_range), age, uid)
)

放一些数据
insert into users (years_range, age , uid) VALUES ( '11_15', 14, 1);
insert into users (years_range, age , uid) VALUES ( '26_30', 28, 3);
insert into users (years_range, age , uid) VALUES ( '16_20', 16, 2);
insert into users (years_range, age , uid) VALUES ( '26_30', 29, 4);
insert into users (years_range, age , uid) VALUES ( '41_45', 41, 5);
insert into users (years_range, age , uid) VALUES ( '21_25', 23, 5);

查询数据
select * from users where years_range in('11_15', '16_20', '21_25', '26_30') and age > 14 and age < 29;

输出
 years_range | age | uid
-------------+-----+-----
16_20 | 16 | 2
21_25 | 23 | 5
26_30 | 28 | 3

此解决方案可能会解决您的问题,并且可以用于小型集群中,其中大约 20 个键 (0_5 ...106_110) 可能具有良好的分布。但是这个解决方案和之前的解决方案一样,不允许 UPDATE 并减少了 key 的分配。优点是你有小的 IN 集。

在 SI 已经允许 IN 子句的完美世界中,我将使用 UUID 作为分区键,将 years_range(设置为birth_year_range)作为 SI 并“过滤”我的数据客户端(如果对 10 > age > 22 感兴趣,我会要求 IN('1991_1995', '1996_2000', '2001_2005', '2006_2010', '2011_2015') 计算并删除我的申请中无用的年份)

哈,
卡罗

关于cql - 如何在cassandra中构建范围查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24968823/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com