如何使用 kdb+ 跟踪任意数量的 IOT 标量流?

How to use kdb+ to track an arbitrary number of IOT scalar streams?

我正在尝试使用 kdb+ 来捕获和聚合从物联网传感器整理的大量感官流。

每个传感器都有一个唯一标识符、一个时间分量 (.z.z) 和一个标量值:

percepts:([]time:`datetime$(); id:`symbol$(); scalar:`float$())

然而,由于数据本质上是时间性的,因此在不同的列中维护单独的 perceptual/sensory 流似乎是合乎逻辑的,即:

time  id_1    id_2 ...
15    0.15     ...
16    ...      1.5

然而,附加到 table 指示性地只支持插入方式的行操作,即感知 insert (.z.z; `id_1; 0.15)

好像我想在此设置中支持大量非静态传感器,在进行转换之前附加上述格式的行似乎是一种反模式根据它们的 id 将行分成列。 possible/necessary 创建一个 table 具有基于新功能流的动态(增长)列数吗?

如何最有效地实现允许插入柱状时间序列数据而无需对基于行的数据进行转换的逻辑?

您可以将数据添加到特定列。为此进行以下更改:

  • 永久或在更新操作期间将 time 列作为键。
  • 使用upsert添加数据并以table格式传递数据。

我在下面提到的更新功能特定于您的示例,但您可以使其更通用。它以传感器名称和传感器数据作为输入。它执行 3 个步骤:

  • 它首先检查 table 是否为空,在这种情况下,将 table 模式设置为输入数据集模式(根据您的示例,它应该是时间和传感器名称列)并且还制作时间作为主键。
  • 如果 table 有数据但新传感器缺少该列,则首先添加一个具有空浮点值的列,然后插入数据。
  • 如果列已经存在,则只需更新数据即可。

    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

关于您的设计的一些要点:

如果所有传感器都没有为每次输入发送数据,那么 table 将有很多空值(类似于稀疏矩阵),这会浪费内存并对查询产生一些影响以及。 在这种情况下,您可以根据您的用例考虑其他设计。例如,不是存储每个时间条目,而是将数据存储在时间桶中。另一种选择是将相关传感器分组在不同的 table 中,而不是将所有传感器都存储在一个中。

您需要考虑的另一点是,如果您继续向其添加传感器并且它有其自身的问题,您将变得很胖 table。此外,它将成为一个单一的瓶颈点,这在未来可能会成为一个问题,并且很难扩展它。

对于小型传感器组,当前的设计很好,但如果您计划在未来添加许多传感器,请考虑其他设计选项。