Jos*_*sef 0 database-design cql cassandra
我需要将传感器读数存储在 cassandra(版本 2!)中。有n 个传感器,其中每个传感器最多可以发送m 个具有不同类型(例如Float、Bool、String)的不同值。这些值必须存储在 cassandra 中。稍后,将主要按时间范围查询值。因此,查询可以是“给我从 2016-05-01 09:00 到 2016-05-15 13:00 的所有读数”。可能有按传感器 ID/类型的过滤器,但主要查询始终是时间。(因此查询可能是“给我 2016 年 5 月 5 日以来传感器 1 和 5 的所有数据”,但很可能不是“给我传感器 1 和 5 的所有数据”)。
对于更详细的查询,如果必须扫描所有数据(受时间和可能的传感器 ID 限制)也是可以的。因此,对于查询“给我 2016 年 5 月 5 日以来传感器 5 的所有传感器数据,其中读数的浮点值大于 1000”,如果 cassandra 必须扫描 2016 年 5 月 5 日以来传感器 5 的所有值,那么就可以了!
我读了很多关于数据建模的博客文章/问题(例如[1] [2] [3] [4] [5] [6]),但有些东西已经有很多年了,我不确定它是否仍然存在正确的方法。
我的主要问题是:
传感器数据将始终按顺序插入,因此不会更改以前的数据,也不会添加时间戳低于当前最大值的数据。
我使用什么数据类型作为时间戳(需要毫秒分辨率)
timeuuid确实
如何定义键?(例如,我是否需要像某些示例使用的每小时主键?如果是,我可以在 cassandra 中合并超过一小时的结果还是需要手动执行此操作?)
使用 Cassandra 进行数据建模的最大秘密是将物理分区的大小限制在可管理的范围内(~100Mb / 1000 万个单元)
在您的情况下,每个传感器的子分区取决于插入率。
如果某些传感器每秒疯狂插入数千个数据点,那么每小时一个分区就是合适的粒度。当然,每小时 1 个分区 ( PRIMARY KEY ((sensor_id, hour), insertion_time_in_timeuuid)) 会限制您的查询能力,例如,如果您想要下午 4 点到晚上 10 点之间某个传感器的数据,您需要发出 6 个查询或使用 IN 子句 ( SELECT * FROM ... WHERE sensor_id=xxx AND hour IN (16, 17, 18, 19, 20, 21, 22))
如果插入率适中,您可以按天/周/月进行子分区。这里没有任何规则,因为这完全取决于数据量。
要记住的关键一点是保持查询方便性与分区大小之间的平衡。
如何添加sensorID以便高效查询
将其作为分区键的组成部分与子分区时间范围一起放置,例如PRIMARY KEY( (sensor_id, hour), insertion_time_in_timeuuid)
传感器数据将始终按顺序插入,因此不会更改以前的数据,也不会添加时间戳低于当前最大值的数据。
CREATE TABLE sensor_data (
sensor_id timeuuid,
partitioning_time_range bigint,
insertion_time_in_timeuuid timeuuid,
float_value float
int_value int,
bool_value bool,
text_value text,
PRIMARY KEY( (sensor_id, hour), insertion_time_in_timeuuid)
) WITH CLUSTERING ORDER BY (insertion_time_in_timeuuid DESC);
Run Code Online (Sandbox Code Playgroud)
为了适应不同类型的数据,只需为数据类型(float_value、bool_value、 ...)创建一个列。在运行时,如果您仅使用 4/5 Cassandra 中的 1 列,则只会在磁盘上插入 1 个物理单元(与关系数据库不同,关系数据库为未使用的列保留空间)
| 归档时间: |
|
| 查看次数: |
1601 次 |
| 最近记录: |