我试图从传感器列表中显示最新值。该列表也应按时间戳排序。
我尝试了两种不同的方法。我在主键中包含了传感器的更新时间:
CREATE TABLE sensors (
customerid int,
sensorid int,
changedate timestamp,
value text,
PRIMARY KEY (customerid, changedate)
) WITH CLUSTERING ORDER BY (changedate DESC);
然后我可以选择这样的列表:
select * from sensors where customerid=0 order by changedate desc;
结果如下:
customerid | changedate | sensorid | value
------------+--------------------------+----------+-------
0 | 2015-07-10 12:46:53+0000 | 1 | 2
0 | 2015-07-10 12:46:52+0000 | 1 | 1
0 | 2015-07-10 12:46:52+0000 | 0 | 2
0 | 2015-07-10 12:46:26+0000 | 0 | 1
问题是,我不仅得到最新结果,而且还得到所有旧值。
如果我从主键中删除了更改的选项,则选择将一起失败。
InvalidRequest: code=2200 [Invalid query] message="Order by is currently only supported on the clustered columns of the PRIMARY KEY, got changedate"
更新传感器值也无选择:
update overview set changedate=unixTimestampOf(now()), value = '5' where customerid=0 and sensorid=0;
InvalidRequest: code=2200 [Invalid query] message="PRIMARY KEY part changedate found in SET part"
此操作失败,因为changedate是主键的一部分。
有没有办法只存储每个传感器的最新值,还能按时间戳保存表格吗?
修改 与此同时,我尝试了另一种方法,只存储最新值。
我使用了这个架构:
CREATE TABLE sensors (
customerid int,
sensorid int,
changedate timestamp,
value text,
PRIMARY KEY (customerid, sensorid, changedate)
) WITH CLUSTERING ORDER BY (changedate DESC);
在插入最新值之前,我会删除所有旧值
DELETE FROM sensors WHERE customerid=? and sensorid=?;
但是这失败了,因为changedate
不是WHERE子句的一部分。
答案 0 :(得分:2)
问题是,我不仅得到最新结果,而且还得到所有旧值。
由于您存储在DESC的CLUSTERING ORDER中,因此获取最新记录总是非常容易,您需要做的就是在查询中添加“LIMIT”,即:
select * from sensors where customerid=0 order by changedate desc limit 10;
最多返回最多10条记录的记录。即使您使用限制,您仍然可以保证获得最新记录,因为您的数据是按此方式订购的。
如果我从主键中删除了更改的选项,则选择将一起失败。
这是因为您不能在不是聚类键(主键的次要部分)的列上订购,除非可能有二级索引,我不建议这样做。
更新传感器值也不是选项
您的更新查询失败,因为在'set'中包含部分主键是不合法的。要完成这项工作,您需要做的就是更新您的查询以在where子句中包含changedate,即:
update overview set value = '5' and sensorid = 0 where customerid=0 and changedate=unixTimestampOf(now())
有没有办法只存储每个传感器的最新值,还能按时间戳保存表格吗?
您可以通过创建一个名为“latest_sensor_data”的单独表来执行此操作,该表具有相同的表定义,但主键除外。主键现在是'customerid,sensorid',因此每个传感器只能有1个记录。创建单独表的过程称为denormalization,是一种常见的使用模式,特别是在Cassandra数据建模中。插入传感器数据时,您现在可以将数据插入“传感器”和“latest_sensor_data”。
CREATE TABLE latest_sensor_data (
customerid int,
sensorid int,
changedate timestamp,
value text,
PRIMARY KEY (customerid, sensorid)
);
在cassandra 3.0中将会引入'materialized views',这将使您不必要,因为您可以使用物化视图为您完成此任务。
现在执行以下查询:
select * from latest_sensor_data where customerid=0
将为该客户的每个传感器提供最新价值。
我建议将'sensors'重命名为'sensor_data'或'sensor_history',以便更清楚地了解数据是什么。此外,您应该将主键更改为“customerid,changedate,sensorid”,因为这样可以让您在同一天拥有多个传感器(这似乎是可能的)。
答案 1 :(得分:2)
你的第一种方法看起来很合理。如果您在查询中添加“限制1”,则只能获得最新结果,或限制2以查看最新的2个结果等。
如果要从表中自动删除旧值,可以在执行插入时为数据点指定TTL(生存时间)。因此,如果您希望将数据点保留10天,可以通过在插入语句中添加“USING TTL 864000”来实现。或者您可以为整个表设置默认TTL。