Cassandra-如何检索最近的值

Cassandra-如何检索最近的值,cassandra,cassandra-2.0,composite-primary-key,Cassandra,Cassandra 2.0,Composite Primary Key,我在Cassandra 2.0.9中定义了下表: CREATE TABLE history ( histid uuid, ddate text, -- Day Date, i.e. 2014-11-20 valtime timestamp, -- value time val text, --value PRIMARY KEY ((histid , ddate)

我在Cassandra 2.0.9中定义了下表:

CREATE TABLE history
(
    histid      uuid,
    ddate           text,       -- Day Date, i.e. 2014-11-20
    valtime         timestamp,  -- value time
    val             text,       --value
    PRIMARY KEY ((histid , ddate), valtime )
)
WITH CLUSTERING ORDER BY (valtime desc)
;
脚本每天向该表插入数千行

我需要能够从这个表中选择,只知道histid。 但是,我使用(histid,ddate)对行进行了分区。 也就是说,我每行有一整天的历史值

为了从这个表中选择特定的histid,我还需要提供ddate列。 例如:

SELECT * FROM history
WHERE histid= cebc4c80-daa6-11e3-bcc2-005056a975a4
AND ddate = '2014-05-16'
;
要获取最新值,我可以执行以下操作:

SELECT * FROM history
WHERE histid= cebc4c80-daa6-11e3-bcc2-005056a975a4
AND ddate = '2014-05-16'
LIMIT 1
;
但是,如果我想要任何给定histid的最新值,我不能在不知道ddate是什么的情况下提交查询,因为它是分区键的一部分

所以…我问,什么是最好的方法

这就是我所做的,但我不知道我不知道这是否合理:

我已经创建了一个辅助表:

 CREATE TABLE history_date
(
    histid          uuid,
    maxdate         timestamp, -- most recent date
    PRIMARY KEY (histid)
);
将行插入历史记录表时,也会使用(histid,valtime)将行插入此表

我们的程序代码可以:

1.  query the history_date table for a particular id
2. take the "maxdate" column (truncate it to yyyy-mm-dd)
3. use the histid and truncated maxdate to query the history table to retrieve the most recent value.
所以这是可行的。但是,这并不是一个好的解决方案

有没有更好的方法来做到这一点,也许只有一张桌子


谢谢您的时间。

正如您所提到的,您不能只知道用两个键分区的表的一个值就进行选择。然而,集群顺序和按限制顺序选项可能会有所帮助,这是您已经使用过的


您可以尝试的一件事是构建一个新的表,该表在更大的日期范围内进行分区,例如
month
。这样,您只需要知道要查询的月份

CREATE TABLE history_by_month(
    histid          uuid,
    ddate           text,       -- Day Date, i.e. 2014-11-20
    valtime         timestamp,  -- value time
    val             text,       --value
    month           text,
    PRIMARY KEY (month, valtime, histid))
WITH CLUSTERING ORDER BY (valtime desc, histid asc);
现在,此查询将返回您要查找的内容:

SELECT * FROM history_by_month
WHERE month = '2014-05'
LIMIT 1;
要记住的唯一一件事是,如果您在一个月内收到太多的条目,那么分区就有可能太大。如果这成为一个问题,你可能会考虑把重点放在一周,也许。< /P>

还有,2.2.9的人应该考虑升级。即使是最新的补丁级别2.1也更加稳定。

我认为解决方案是直截了当的,没有必要让事情复杂化。 只需在“histid”上设置分区键,在“ddate”上设置集群键。因此,您的DDL应该如下所示

创建表历史记录 ( 组织样uuid, ddate文本, valtime时间戳, 瓦尔文本, 主键((histid)、ddate、valtime) ) ;

您可以从以下任意组合进行查询(但请确保where子句中的顺序相同) a) 仅查询histid b) 查询histid和dddate c) histid、dddate和valtime查询


让我知道这是否适合您,或者您还有问题吗?

针对Cassandra的数据建模是一种不同的思维方式,冗余数据/查询表方法是正确的方法。@BryceAtNetwork23-谢谢。是的,有时候很难让你的头脑清醒。感谢您的反馈。@i我认为这很难。关键是要认识到需要一种不同的心态,你已经越过了这个障碍,所以你走在了正确的道路上。比许多似乎从未“了解它”的人更进一步:)坚持下去,随着时间的推移,它会变得更有意义。@DonBranson感谢20多年来使用“其他”主要数据库毁了我:)@iamoracle-Heh。好吧,我已经编写了足够长的时间了,我记得上一次SQL数据库的范式转换。拥有更大的分区并不能解决问题。这仍然是一个相同的问题:如何计算用于查询的月份。我只是想知道,除了OP提出的一个解决方案之外,是否还有一个通用的解决方案?@IhorKaharlichenko不幸的是,Cassandra有非常严格的查询要求,需要了解一些时间范围的知识来缩小范围。