Как использовать 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

Некоторые моменты относительно вашего дизайна:

Если все датчики не отправляют данные для каждого временного ввода, таблица будет иметь много нулевых значений (подобно разреженной матрице), что приведет к пустой трате памяти и также окажет некоторое влияние на запросы. В этом случае вы можете рассмотреть другой дизайн в зависимости от вашего варианта использования. Например, вместо того, чтобы хранить каждый раз запись, сохраняйте данные во временных интервалах. Другим вариантом является группирование связанных датчиков в другую таблицу вместо хранения всех в одной.

Еще один момент, который вам нужно учитывать, это то, что у вас будет толстый стол, если вы продолжите добавлять к нему датчики, и у него есть свои проблемы. Кроме того, это станет единственным узким местом, которое может стать проблемой в будущем, и масштабировать его будет сложно.

Для небольших наборов датчиков текущая конструкция хороша, но если вы планируете добавить много датчиков в будущем, посмотрите другие варианты дизайна.

Другие вопросы по тегам