【问题标题】:Cassandra best practice to ORDER BY using PRIMARY KEYCassandra 使用 PRIMARY KEY 排序的最佳实践
【发布时间】:2020-12-01 09:32:17
【问题描述】:

最初我有一个这样的 cassandra 表:

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';

谢谢!

【问题讨论】:

    标签: database cassandra data-modeling cassandra-3.0


    【解决方案1】:

    CLUSTERING ORDER 在每个分区中强制执行磁盘排序顺序。因此,不可能通过您正在分区的同一键进行排序。由id 进行分区将面临类似的挑战,因为CLUSTERING ORDER BY open_time 将仅在每个id执行。

    我想知道这里的最佳做法是什么。

    就像我今天早些时候在answer to a similar question 中提到的那样,此类模型通常通过时间分桶来解决。要选择最佳“存储桶”,您需要了解您的业务案例,例如每天的条目数以及查询要求。

    举个例子,假设那个月效果最好。如果每一行包含一个值“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;
    

    由于结果存储在每个month_bucket 中,并按open_time 降序排列,因此该查询将返回最近的条目。

    我为 DataStax(几年前)写了一篇与此问题相关的文章。它已被移动到他们网站的一个新部分,该部分对格式进行了冲洗,但内容肯定在那里。读一读;希望对您有所帮助:We Shall Have Order!

    【讨论】:

      【解决方案2】:

      如果 id 被提及作为主键,它必须包含在 where 子句中,否则它需要允许过滤。 您可以尝试使用“Select max(open_time)....”进行查询,否则您可以使用上面的 id,它会随着每条记录的增加而增加,结果,具有最高值的 id 总是有最新的记录。

      【讨论】:

        猜你喜欢
        • 2022-01-27
        • 2015-03-25
        • 2016-05-19
        • 1970-01-01
        • 1970-01-01
        • 2015-07-13
        • 1970-01-01
        • 1970-01-01
        • 2018-11-24
        相关资源
        最近更新 更多