如果我的表定义如下:
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;
...但是如何有效地为每一行选择最新的时间戳和值?
常规SQL中的GROUP BY schedule_id
或列范围查询(在CQL 3中不再支持)。
答案 0 :(得分: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
(这假设您的数据始终以单调增加的时间输入,例如来自实时Feed)。
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';