Как использовать kdb+ для отслеживания произвольного количества скалярных потоков IOT?
Я пытаюсь использовать kdb+ для захвата и создания агрегаций на ряде сенсорных потоков, сопоставленных с iot сенсорами.
Каждый датчик имеет уникальный идентификатор, составляющий время (.zz) и скалярное значение:
percepts:([]time:`datetime$(); id:`symbol$(); scalar:`float$())
Однако поскольку данные носят временный характер, представляется логичным поддерживать отдельные перцептивные / сенсорные потоки в разных столбцах, а именно:
time id_1 id_2 ...
15 0.15 ...
16 ... 1.5
Однако добавление к таблице ориентировочно поддерживает только строковые операции в режиме вставки, т.е. воспринимает вставку (.zz; `id_1; 0,15)
Если в этой настройке я хотел бы поддержать большое и нестатическое число датчиков, то было бы похоже на анти-шаблон для добавления строк вышеупомянутого формата, прежде чем выполнять преобразование для преобразования строк в столбцы на основе их идентификатор. Возможно ли / необходимо создать таблицу с динамическим (растущим) числом столбцов на основе новых потоков функций?
Как наиболее эффективно реализовать логику, которая позволяет вставлять столбчатые данные временных рядов, предотвращая необходимость преобразования данных на основе строк?
1 ответ
Вы можете добавить данные в определенный столбец. Для этого внесите следующие изменения:
- Сделать
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
Некоторые моменты относительно вашего дизайна:
Если все датчики не отправляют данные для каждого временного ввода, таблица будет иметь много нулевых значений (подобно разреженной матрице), что приведет к пустой трате памяти и также окажет некоторое влияние на запросы. В этом случае вы можете рассмотреть другой дизайн в зависимости от вашего варианта использования. Например, вместо того, чтобы хранить каждый раз запись, сохраняйте данные во временных интервалах. Другим вариантом является группирование связанных датчиков в другую таблицу вместо хранения всех в одной.
Еще один момент, который вам нужно учитывать, это то, что у вас будет толстый стол, если вы продолжите добавлять к нему датчики, и у него есть свои проблемы. Кроме того, это станет единственным узким местом, которое может стать проблемой в будущем, и масштабировать его будет сложно.
Для небольших наборов датчиков текущая конструкция хороша, но если вы планируете добавить много датчиков в будущем, посмотрите другие варианты дизайна.