time-series - 如何使用 kdb+ 跟踪任意数量的 IOT 标量流?
问题描述
我正在尝试使用 kdb+ 来捕获并聚合从物联网传感器整理的许多感官流。
每个传感器都有一个唯一标识符、一个时间分量 (.zz) 和一个标量值:
percepts:([]time:`datetime$(); id:`symbol$(); scalar:`float$())
然而,由于数据本质上是时间的,在不同的列中维护单独的感知/感觉流似乎是合乎逻辑的,即:
time id_1 id_2 ...
15 0.15 ...
16 ... 1.5
然而,附加到表指示性仅支持插入方式的行操作,即感知插入(.zz;`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
关于您的设计的一些要点:
如果所有传感器都没有为每个时间条目发送数据,那么该表将有很多空值(类似于稀疏矩阵),这将浪费内存并且也会对查询产生一些影响。在这种情况下,您可以根据您的用例考虑其他设计。例如,不是存储每个时间条目,而是将数据存储在时间桶中。另一种选择是将相关传感器分组到不同的表中,而不是全部存储在一个表中。
您需要考虑的另一点是,如果您继续向其中添加传感器,您将拥有一个胖表,并且它有其自身的问题。此外,它将成为一个单一的瓶颈点,这可能是未来的一个问题,并且很难扩展它。
对于小型传感器组,当前的设计很好,但如果您计划将来添加许多传感器,那么请考虑其他设计选项。
推荐阅读
- asp.net-core - 浏览器如何向服务器发出取消信号?
- javascript - 如何取回单选按钮的检查值?
- imagemagick - 带有 Nivida GPU 的 ImageMagick
- java - 使用 Spring Boot 和 Spring 集成的异步邮件接收
- mysql - SELECT 不重复,除非被其他值打断
- oracle - Oracle中如何为现有表添加自动增量
- html - 有没有办法使用纯 css 自定义 html5 type=date UI?
- next.js - 设置 Storybook 以使用 Next.js 的 Link 标签
- c++ - 在 C++ 中为指定的字符着色
- java - Java android 10 问题与创建文件