我正在尝试使用kdb +来捕获和处理从物联网传感器整理的许多感觉流的聚合。
每个传感器都有一个唯一的标识符,一个时间分量(.z.z)和一个标量值:
percepts:([]time:`datetime$(); id:`symbol$(); scalar:`float$())
但是,由于数据本质上是暂时的,因此在不同的列中维护单独的感知/感觉流似乎是合乎逻辑的,即:
time id_1 id_2 ...
15 0.15 ...
16 ... 1.5
但是,追加到表仅指示以插入方式支持行操作,即,感知插入(.z.z;ʻid_1; 0.15)
似乎我想在此设置中支持大量的非静态传感器,在执行转换以将行转换为基于列的列之前,添加上述格式的行似乎是一种反模式。他们的身份证是否有可能/有必要根据新功能流创建具有动态(增长)列数的表?
如何最有效地实现允许插入列时间序列数据的逻辑,从而避免了对基于行的数据进行转换的需要?
最佳答案
您可以将数据添加到特定列。为此,请进行以下更改:
time
列永久或在更新操作期间作为键。 upsert
可添加数据并以表格式传递数据。 我下面提到的更新功能特定于您的示例,但您可以使其更通用。它以传感器名称和传感器数据为输入。它执行3个步骤:
q)t:() / table to store all sensors data
q)upd:{[s;tbl] `t set $[0=count t;`time xkey 0#tbl;not s in cols t;![t;();0b;enlist[s]!enlist count[t]#0Nf];t] upsert tbl}
q)upd[`id1;([]time:1#.z.z;id1:1#14.4)]
q)upd[`id2;([]time:1#.z.z;id2:1#2.3)]
time id1 id2
--------------------------------
2019.08.26T13:35:43.203 14.4
2019.08.26T13:35:46.861 2.3
有关您的设计的一些要点:
如果不是所有的传感器都不会在每次输入时都发送数据,则该表将具有大量的空值(类似于稀疏矩阵),这将浪费内存,并且也会对查询产生一些影响。
在这种情况下,您可以根据用例考虑其他设计。例如,将数据存储在时间段中,而不是存储每个时间条目。另一种选择是将相关传感器分组在不同的表中,而不是全部存储在一个表中。
您需要考虑的另一点是,如果继续向其添加传感器,将会有一个胖表,这有其自身的问题。而且,它将成为单个瓶颈点,将来可能会成为一个问题,并且很难扩展。
对于小型传感器组,当前的设计不错,但是如果您打算将来增加许多传感器,请考虑其他设计方案。
关于time-series - 如何使用kdb +跟踪任意数量的IOT标量流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57645836/