使用 PRIMARY KEY 进行 ORDER BY 的 Cassandra 最佳实践
Cassandra best practice to ORDER BY using PRIMARY KEY
原来我有一个像这样的cassandra table:
CREATE TABLE table (
open_time timestamp,
open double,
close double,
high double,
low double,
volume bigint,
PRIMARY KEY(open_time));
open_time | close | high | low | open | volume
---------------------------------+--------+--------+-------+--------+--------
2020-08-05 06:00:00.000000+0000 | 181.53 | 184.32 | 181.1 | 184.32 | 100
2020-08-04 06:00:00.000000+0000 | 181.53 | 184.32 | 181.1 | 184.32 | 100
我需要执行查询以获取最新的 open_time。在注意到
这样的查询之后
SELECT open_time FROM table ORDER BY open_time DESC LIMIT 1;
不允许,我想知道这里的最佳做法是什么。
我的想法是添加一个 id 列,我可以使用 open_time 作为聚类顺序。类似于:
CREATE TABLE table (
id int,
open_time timestamp,
open double,
close double,
high double,
low double,
volume bigint,
PRIMARY KEY(id, open_time)
)
WITH CLUSTERING ORDER BY (open_time DESC);
这是完成工作的有效解决方案还是有更好的方法,例如没有额外 id 列的东西,因为我永远不会查询 id itslef。
最多的查询是这样的:
SELECT * FROM table WHERE open_time >= '2013-01-01 00:00:00+0200' AND open_time <= '2013-08-13 23:59:00+0200';
谢谢!
如果提到id作为主键,它必须包含在where子句中否则需要允许过滤。
您可以尝试使用“Select max(open_time)....”进行查询,否则您可以像上面那样使用 id,它将随着每条记录和结果而增加,具有最高值的 id 将始终具有最新记录。
CLUSTERING ORDER
在每个分区内强制执行 on-disk 排序顺序。因此,不可能通过您正在分区的相同键进行排序。按 id
进行分区将面临类似的挑战,因为 CLUSTERING ORDER BY open_time
将仅在 内 每个 id
.
中执行
I wonder what's the best practice here.
像这样的模型通常通过时间分桶来解决,正如我今天早些时候在 中提到的那样。要 select 最好的“桶”,您需要了解您的业务案例,例如每天的条目数,以及查询要求。
举个例子,假设那个月效果最好。如果每行包含一个值 'YEAR-MONTH',PK 定义将如下所示:
PRIMARY KEY (month_bucket,open_time))
WITH CLUSTERING ORDER BY (open_time DESC);
那么,您可以支持这样的查询:
SELECT * FROM table
WHERE month_bucket = '2013-08'
AND open_time >= '2013-08-01 00:00:00+0200' AND open_time <= '2013-08-13 23:59:00+0200';
同样,查询最近的条目只需要最近(当前?)月份作为参数:
SELECT * FROM table
WHERE month_bucket = '2020-08'
LIMIT 1;
由于结果存储在按 open_time
降序排列的每个 month_bucket
中,该查询将 return most-recent 条目。
我为 DataStax(几年前)写了一篇与此问题相关的文章。它已移至其网站的新部分,该部分对格式进行了处理,但内容肯定在那里。读一读;希望对您有所帮助:We Shall Have Order!
原来我有一个像这样的cassandra table:
CREATE TABLE table (
open_time timestamp,
open double,
close double,
high double,
low double,
volume bigint,
PRIMARY KEY(open_time));
open_time | close | high | low | open | volume
---------------------------------+--------+--------+-------+--------+--------
2020-08-05 06:00:00.000000+0000 | 181.53 | 184.32 | 181.1 | 184.32 | 100
2020-08-04 06:00:00.000000+0000 | 181.53 | 184.32 | 181.1 | 184.32 | 100
我需要执行查询以获取最新的 open_time。在注意到
这样的查询之后SELECT open_time FROM table ORDER BY open_time DESC LIMIT 1;
不允许,我想知道这里的最佳做法是什么。
我的想法是添加一个 id 列,我可以使用 open_time 作为聚类顺序。类似于:
CREATE TABLE table (
id int,
open_time timestamp,
open double,
close double,
high double,
low double,
volume bigint,
PRIMARY KEY(id, open_time)
)
WITH CLUSTERING ORDER BY (open_time DESC);
这是完成工作的有效解决方案还是有更好的方法,例如没有额外 id 列的东西,因为我永远不会查询 id itslef。
最多的查询是这样的:
SELECT * FROM table WHERE open_time >= '2013-01-01 00:00:00+0200' AND open_time <= '2013-08-13 23:59:00+0200';
谢谢!
如果提到id作为主键,它必须包含在where子句中否则需要允许过滤。 您可以尝试使用“Select max(open_time)....”进行查询,否则您可以像上面那样使用 id,它将随着每条记录和结果而增加,具有最高值的 id 将始终具有最新记录。
CLUSTERING ORDER
在每个分区内强制执行 on-disk 排序顺序。因此,不可能通过您正在分区的相同键进行排序。按 id
进行分区将面临类似的挑战,因为 CLUSTERING ORDER BY open_time
将仅在 内 每个 id
.
I wonder what's the best practice here.
像这样的模型通常通过时间分桶来解决,正如我今天早些时候在
举个例子,假设那个月效果最好。如果每行包含一个值 'YEAR-MONTH',PK 定义将如下所示:
PRIMARY KEY (month_bucket,open_time))
WITH CLUSTERING ORDER BY (open_time DESC);
那么,您可以支持这样的查询:
SELECT * FROM table
WHERE month_bucket = '2013-08'
AND open_time >= '2013-08-01 00:00:00+0200' AND open_time <= '2013-08-13 23:59:00+0200';
同样,查询最近的条目只需要最近(当前?)月份作为参数:
SELECT * FROM table
WHERE month_bucket = '2020-08'
LIMIT 1;
由于结果存储在按 open_time
降序排列的每个 month_bucket
中,该查询将 return most-recent 条目。
我为 DataStax(几年前)写了一篇与此问题相关的文章。它已移至其网站的新部分,该部分对格式进行了处理,但内容肯定在那里。读一读;希望对您有所帮助:We Shall Have Order!