Database design 卡桑德拉:如何对传感器数据的时间序列建模?

Database design 卡桑德拉:如何对传感器数据的时间序列建模?,database-design,cassandra,cql,Database Design,Cassandra,Cql,我需要在cassandra(版本2!)中存储传感器读数。 共有n个传感器,每个传感器最多可发送m个不同类型的值(例如浮点、布尔、字符串)。这些值必须存储在cassandra中。稍后,将主要按时间范围查询值。因此,查询可以是“给我2016-05-01 09:00到2016-05-15 13:00的所有读数”。可以按传感器ID/类型进行筛选,但主查询始终是时间。(因此,查询可以是“提供2016-05-05传感器1和5的所有数据”,但很可能不是“提供传感器1和5的所有数据”) 对于更详细的查询,如果必

我需要在cassandra(版本2!)中存储传感器读数。 共有n个传感器,每个传感器最多可发送m个不同类型的值(例如浮点、布尔、字符串)。这些值必须存储在cassandra中。稍后,将主要按时间范围查询值。因此,查询可以是“给我2016-05-01 09:00到2016-05-15 13:00的所有读数”。可以按传感器ID/类型进行筛选,但主查询始终是时间。(因此,查询可以是“提供2016-05-05传感器1和5的所有数据”,但很可能不是“提供传感器1和5的所有数据”)

对于更详细的查询,如果必须扫描所有数据(受时间和可能的传感器ID限制),则可以。因此,对于查询“给出2016-05-05年传感器5的所有传感器数据,其中读数的浮动值大于1000”,如果cassandra必须扫描2016-05-05年传感器5的所有值,则可以

我读了很多关于数据建模的博客文章/问题,(例如),但有些东西已经过时了,我不确定这是否仍然是正确的方法

我的主要问题是:

  • 时间戳使用什么数据类型(需要毫秒分辨率)
  • 如何定义键?(例如,我是否需要一些示例中使用的每小时一次的主键?如果需要,我是否可以在cassandra中组合一小时以上的结果,或者我是否需要手动进行组合?)
  • 如何添加sensorID,以便能够高效地查询它
传感器数据始终按顺序插入,因此不会更改以前的数据,也不会添加时间戳低于当前最大值的数据

时间戳使用什么数据类型(需要毫秒分辨率)

timeuuid

如何定义键?(例如,我是否需要一些示例中使用的每小时一次的主键?如果需要,我是否可以在cassandra中组合一小时以上的结果,或者我是否需要手动进行组合?)

使用Cassandra进行数据建模的最大秘密是将物理分区的大小限制在可管理的范围内(约100Mb/1000万个单元)

在您的情况下,每个传感器的子分区取决于插入速率

如果某些传感器以每秒数千个数据点的速度插入数据,那么每小时一个分区就是合适的粒度。当然,每小时1个分区(
主键((传感器id,hour),插入时间id)
)会限制你的查询能力,例如,如果你想在下午4点到晚上10点之间查询某个传感器的数据,你需要发出6个查询或使用in子句(
选择*FROM…,其中传感器id=xxx,hour in(16、17、18、19、20、21、22)

如果插入率适中,则可以按天/周/月细分分区。这里没有规则,因为它完全取决于数据量

要记住的关键是要在查询的易用性和分区大小之间保持平衡

如何添加sensorID,以便能够高效地查询它

将其与子分区时间范围一起作为分区键的一个组成部分,例如
主键((传感器id,小时),插入时间\u in\u timeuuid)

传感器数据始终按顺序插入,因此不会更改以前的数据,也不会添加时间戳低于当前最大值的数据

为了适应不同类型的数据,只需为数据类型创建一列(
float\u value
bool\u value
,…)。在运行时,如果只使用4/5列中的1列,Cassandra将只在磁盘上插入1个物理单元(与关系数据库不同,为未使用的列保留空间)

时间戳使用什么数据类型(需要毫秒分辨率)

timeuuid

如何定义键?(例如,我是否需要一些示例中使用的每小时一次的主键?如果需要,我是否可以在cassandra中组合一小时以上的结果,或者我是否需要手动进行组合?)

使用Cassandra进行数据建模的最大秘密是将物理分区的大小限制在可管理的范围内(约100Mb/1000万个单元)

在您的情况下,每个传感器的子分区取决于插入速率

如果某些传感器以每秒数千个数据点的速度插入数据,那么每小时一个分区就是合适的粒度。当然,每小时1个分区(
主键((传感器id,hour),插入时间id)
)会限制你的查询能力,例如,如果你想在下午4点到晚上10点之间查询某个传感器的数据,你需要发出6个查询或使用in子句(
选择*FROM…,其中传感器id=xxx,hour in(16、17、18、19、20、21、22)

如果插入率适中,则可以按天/周/月细分分区。这里没有规则,因为它完全取决于数据量

要记住的关键是要在查询的易用性和分区大小之间保持平衡

如何添加sensorID,以便能够高效地查询它

将其与子分区时间范围一起作为分区键的一个组成部分,例如
主键((传感器id,小时),插入时间\u in\u timeuuid)

传感器数据始终按顺序插入,因此不会更改以前的数据,也不会添加时间戳低于当前最大值的数据


为了适应不同类型的数据,只需为数据类型创建一列(
float\u value
bool\u value
,…)。在运行时,如果只使用4/5列中的1列,Cassandra将只在磁盘上插入1个物理单元(与关系数据库不同,为未使用的列保留空间)

非常感谢您的回答。插入速率是每分钟几百个值,所以我可以从每周分区开始。正确的(性能)是什么
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);