use*_*859 7 time-series cassandra
我正在尝试从传感器列表中显示最新值.该列表还应按时间戳排序.
我尝试了两种不同的方法.我在主键中包含了传感器的更新时间:
CREATE TABLE sensors (
customerid int,
sensorid int,
changedate timestamp,
value text,
PRIMARY KEY (customerid, changedate)
) WITH CLUSTERING ORDER BY (changedate DESC);
Run Code Online (Sandbox Code Playgroud)
然后我可以选择这样的列表:
select * from sensors where customerid=0 order by changedate desc;
Run Code Online (Sandbox Code Playgroud)
结果如下:
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
Run Code Online (Sandbox Code Playgroud)
问题是,我不仅得到最新结果,而且还得到所有旧值.
如果我从主键中删除了更改的选项,则选择将一起失败.
InvalidRequest: code=2200 [Invalid query] message="Order by is currently only supported on the clustered columns of the PRIMARY KEY, got changedate"
Run Code Online (Sandbox Code Playgroud)
更新传感器值也是没有选择:
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"
Run Code Online (Sandbox Code Playgroud)
这会失败,因为changedate是主键的一部分.
有没有可能的方法只存储每个传感器的最新值,并保持按时间戳排序表?
编辑: 在此期间我尝试了另一种方法,只存储最新的值.
我使用了这个架构:
CREATE TABLE sensors (
customerid int,
sensorid int,
changedate timestamp,
value text,
PRIMARY KEY (customerid, sensorid, changedate)
) WITH CLUSTERING ORDER BY (changedate DESC);
Run Code Online (Sandbox Code Playgroud)
在插入最新值之前,我会删除所有旧值
DELETE FROM sensors WHERE customerid=? and sensorid=?;
Run Code Online (Sandbox Code Playgroud)
但这失败了,因为changedate它不是WHERE子句的一部分.
问题是,我不仅得到最新结果,还得到所有旧值。
由于您存储在 DESC 的 CLUSTERING ORDER 中,因此获取最新记录总是很容易,您所需要做的就是在查询中添加“LIMIT”,即:
select * from sensors where customerid=0 order by changedate desc limit 10;
Run Code Online (Sandbox Code Playgroud)
最多会返回 10 条更改最高的记录。即使您使用限制,您仍然可以保证获得最新记录,因为您的数据是这样排序的。
如果我从主键中删除更改数据,则选择会全部失败。
这是因为您无法对不是聚集键(主键的辅助部分)的列进行排序,除非可能带有辅助索引,但我不建议这样做。
更新传感器值也是没有选择的
您的更新查询失败,因为在“set”中包含部分主键是不合法的。为了使这项工作有效,您需要做的就是更新您的查询以在 where 子句中包含 Changedate,即:
update overview set value = '5' and sensorid = 0 where customerid=0 and changedate=unixTimestampOf(now())
Run Code Online (Sandbox Code Playgroud)
有没有可能的方法来仅存储每个传感器的最新值,并保持表按时间戳排序?
您可以通过创建一个名为“latest_sensor_data”的单独表来完成此操作,该表具有相同的表定义(主键除外)。主键现在为“customerid,sensorid”,因此每个传感器只能有 1 条记录。创建单独表的过程称为非规范化,是一种常见的使用模式,特别是在 Cassandra 数据建模中。当您插入传感器数据时,您现在可以将数据插入到“sensors”和“latest_sensor_data”中。
CREATE TABLE latest_sensor_data (
customerid int,
sensorid int,
changedate timestamp,
value text,
PRIMARY KEY (customerid, sensorid)
);
Run Code Online (Sandbox Code Playgroud)
在 cassandra 3.0 中,将引入“物化视图”,这将不再需要此操作,因为您可以使用物化视图来完成此操作。
现在执行以下查询:
select * from latest_sensor_data where customerid=0
Run Code Online (Sandbox Code Playgroud)
将为您提供该客户每个传感器的最新值。
我建议将“传感器”重命名为“sensor_data”或“sensor_history”,以使其更清楚数据是什么。此外,您应该将主键更改为“customerid、changedate、sensorid”,因为这将允许您在同一日期拥有多个传感器(这似乎是可能的)。
| 归档时间: |
|
| 查看次数: |
7209 次 |
| 最近记录: |