1

如果我有一个定义如下的表:

CREATE TABLE metrics (
  schedule_id int,
  time timestamp,
  value double,
  PRIMARY KEY (schedule_id, time)
);

为单个键选择最新的时间戳和值非常简单:

SELECT time, value FROM metrics WHERE schedule_id = 1 ORDER BY time DESC LIMIT 1;

...但是如何有效地为每一行选择最新的时间戳和值?

类似于GROUP BY schedule_id常规 SQL 或列范围查询(在 CQL 3 中不再支持)。

4

1 回答 1

0

这是一个幼稚的解决方案,因为我不知道您的用例将如何容忍由于 Cassandra 的最终一致和最后写入获胜语义而导致的数据差异。但与 Cassandra 中的情况一样,支持不同视图(或查询方式)数据的方法是将其非规范化并以多种方便的方式存储。

CREATE TABLE latest_metrics (
    metric_name text,
    schedule_id int,
    latest_time timestamp,
    latest_value double,
    PRIMARY KEY (metric_name, schedule_id)
);

当您将数据插入metrics时,同时也写入latest_metrics(这假设您的数据始终以单调递增的时间输入,例如来自实时提要)。

INSERT INTO metrics (schedule_id, time, value) VALUES (?, ?, ?);
INSERT INTO latest_metrics (metric_name, schedule_id, latest_time, latest_value)
    VALUES ('WellKnownIdentifier', ?, ?, ?);

在这种情况下,“最新”实际上是根据写入记录的时间而不是实际的时间戳字段值。如果您正在摄取带有交错时间的数据,您可能必须在应用程序端处理这个问题。您还可以在 Cassandra 2.x 中使用新的比较和设置 (CAS) 功能,但这样做所需的 Paxos 进程将严重影响您的写入性能:

INSERT INTO latest_metrics (...) VALUES (...) IF latest_time <= ?;

如果所有这些假设都适用于您的数据,您可以轻松地查询所有计划的“最新”值:

SELECT schedule_id, latest_time, latest_value FROM latest_metrics WHERE metric_name = 'WellKnownIdentifier';
于 2014-04-26T19:03:01.287 回答