Пример моделирования данных в сценариях умного дома

Данный документ является четвёртой главой серии «Моделирование временных рядов». Компания YMatrix считает, что проектирование моделей данных напрямую влияет на ценность потребления и использования данных. Поэтому помимо технического описания мы посвящаем всю главу тому, чтобы дать вам чёткое понимание концепции, применения и разработки моделей временных рядов.

  • Первая статья — «Что такое модель данных временных рядов?» — ответит на несколько глубоких вопросов и поможет вам ясно понять саму концепцию модели данных временных рядов.
  • Вторая статья — «Идеи моделирования временных последовательностей» — попытается представить рекомендации по подходам к проектированию от YMatrix с теоретической точки зрения.
  • Третья и четвёртая статьи — примеры моделирования данных в сценариях интернета вещей и умного дома (то есть данный документ). Под руководством «идей моделирования временных последовательностей» они демонстрируют лучшие практики моделирования различных временных сценариев в YMatrix.

Примечание!
Данный материал приведён исключительно в качестве справочного примера. Перед началом проектирования модели рекомендуется внимательно изучить хотя бы архитектуру YMatrix и принципы работы компонентов. Описание принципов работы компонентов см. в главе «Справочное руководство».

1 Что такое умный дом?

Умный дом — один из типичных сценариев применения Интернета вещей. Умный дом (автоматизация дома) строится на базе жилой платформы и использует интегрированные технологии проводки, сетевых коммуникаций, технологий безопасности, автоматического управления и аудио-видео технологий для объединения объектов, связанных с жизнью в доме, с целью создания эффективной системы управления бытовыми приборами и домашними делами. Это повышает безопасность, удобство, комфорт и эстетическую составляющую жизни в доме, обеспечивая экологически чистую и энергосберегающую среду.

2 Лучшие практики моделирования данных в умном доме

Можно представить, что вы являетесь разработчиком или специалистом по эксплуатации платформы B показателей умного кондиционера. Теперь вы хотите выполнить моделирование и проектирование бизнес-логики этой платформы в YMatrix. Возможные шаги следующие:

Порядковый номер Этап
1 Исследование требований
2 Проектирование и реализация модели
3 Тестирование модели

2.1 Исследование требований

  • Структура данных платформы показателей умного кондиционера B:

Категория, продукт, оборудование и показатель образуют уникальный идентификатор для каждого значения показателя. Категория, продукт и оборудование являются статическими наборами меток (tagsets) таблицы показателей кондиционера, а показатель — это динамическое имя метрики.

  • Характеристики данных платформы показателей умного кондиционера B:

    • Объём данных: количество продуктов — порядка 100 тыс., каждое изделие производит различное количество устройств, обычно от 100 тыс. до 1 млн, количество показателей — в пределах 100.
    • Показатели продукции: показатели изделий одной категории похожи, но не полностью идентичны.
    • Тип метрик: неопределён.
  • Характеристики запросов платформы показателей умного кондиционера B:

    • Запрос последнего значения: получить последнее значение определённого показателя конкретного устройства определённого продукта.
    • Запрос по группе одного продукта: получить показатели и соответствующие значения всех устройств определённого продукта за определённый день.
  • Полный поток данных:

Предварительная обработка и детализированные данные на стороне продукта (сенсора) -> Облако -> YMatrix -> Приложение умного дома

Вывод: после тщательного и всестороннего предварительного исследования мы пришли к выводу, что на начальном этапе проектирования модели данных в данном сценарии умного дома в YMatrix трудно точно определить параметры. Объём данных и количество устройств велики. Следует использовать узкую таблицу, типы text и float являются базовыми, а в качестве основного механизма хранения следует выбрать движок MARS3, обладающий высокой степенью сжатия.

2.2 Проектирование и реализация модели

2.2.1 Структура таблицы

Создайте несколько узких таблиц в зависимости от типа данных метрик.

=# CREATE TABLE public.iot_float (
    product_type text, 
    product text,
    device text,
    metric text,
    value float4,
    ts timestamp with time zone
)
USING MARS3
DISTRIBUTED BY (product_type,product,device)
ORDER BY (device,ts,product_type,product)
PARTITION BY range(ts)
(
 START ('2023-01-15') INCLUSIVE
 END ('2023-01-22') EXCLUSIVE
 EVERY (interval '1 hour'),
 DEFAULT PARTITION default_p
);
=# CREATE TABLE public.iot_text (
    product_type text, 
    product text,
    device text, 
    metric text,
    value text,
    ts timestamp with time zone
)
USING MARS3
DISTRIBUTED BY (product_type,product,device)
ORDER BY (device,ts,product_type,product)
PARTITION BY range(ts)
(
 START ('2023-01-15') INCLUSIVE
 END ('2023-01-22') EXCLUSIVE
 EVERY (interval '1 hour'),
 DEFAULT PARTITION default_p
);

В этом примере:

  • Три столбца: product_type, product, device;
  • Метрика — столбец metric, значение метрики — столбец value;
  • Типы показателей: float и text;
  • Используются product_type, product, device в качестве ключа распределения;
  • Используются device, ts, product_type, product в качестве ключей сортировки;
  • Используется ts в качестве ключа партиционирования;
  • От 2023-01-15 до 2023-01-22 создаётся одна партиция в час.

2.3 Тестирование модели

Порядковый номер План теста SQL-запрос
1 Просмотр последних 10 записей SELECT * FROM <Table Name> ORDER BY ts DESC LIMIT 10
2 Запрос общего количества строк SELECT COUNT(*) FROM <table name>
3 Запрос всех последних показателей, переданных определённым устройством SELECT * FROM <Table name> WHERE <Device tag column name> = '<Device tag value>' ORDER BY <Timestamp column name> DESC LIMIT 1
...

Вставка 100 тестовых записей в таблицу iot_float.

=# INSERT INTO public.iot_float (product_type, product, device, metric, value, ts)
SELECT
    CASE (random() * 3)::int
        WHEN 0 THEN 'sensor'
        WHEN 1 THEN 'actuator'
        WHEN 2 THEN 'gateway'
        ELSE 'others'
    END AS product_type,
    'product_' || (random() * 10 + 1)::int AS product,
    'device_' || (random() * 100 + 1)::int AS device,
    CASE (random() * 5)::int
        WHEN 0 THEN 'temperature'
        WHEN 1 THEN 'humidity'
        WHEN 2 THEN 'pressure'
        WHEN 3 THEN 'voltage'
        WHEN 4 THEN 'current'
        ELSE 'others'
    END AS metric,
    random() * 100 AS value,
    timestamp '2023-01-15 00:00:00+00' + (random() * (timestamp '2023-01-22 00:00:00+00' - timestamp '2023-01-15 00:00:00+00')) AS ts
FROM generate_series(1, 100);

Вставка 100 тестовых записей в таблицу iot_text.

=# INSERT INTO public.iot_text (product_type, product, device, metric, value, ts)
SELECT
    CASE (random() * 3)::int
        WHEN 0 THEN 'sensor'
        WHEN 1 THEN 'actuator'
        WHEN 2 THEN 'gateway'
        ELSE 'others'
    END AS product_type,
    'product_' || (random() * 10 + 1)::int AS product,
    'device_' || (random() * 100 + 1)::int AS device,
    CASE (random() * 5)::int
        WHEN 0 THEN 'status'
        WHEN 1 THEN 'message'
        WHEN 2 THEN 'error'
        WHEN 3 THEN 'warning'
        WHEN 4 THEN 'log'
        ELSE 'others'
    END AS metric,
    'value_' || (random() * 1000 + 1)::int AS value,
    timestamp '2023-01-15 00:00:00+00' + (random() * (timestamp '2023-01-22 00:00:00+00' - timestamp '2023-01-15 00:00:00+00')) AS ts
FROM generate_series(1, 100);

Результаты тестирования:

  1. Получение последних 10 записей из таблицы iot_float
    =# SELECT * FROM iot_float ORDER BY ts DESC LIMIT 10;
    product_type |  product   |  device   |   metric    |   value    |              ts
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    actuator     | product_3  | device_24 | others     |  38.504875 | 2023-01-21 18:38:55.188439+08
    others      | product_10 | device_59 | voltage     |  35.519894 | 2023-01-21 18:11:00.799357+08
    sensor       | product_11 | device_15 | temperature |  74.955025 | 2023-01-21 17:04:56.706237+08
    others      | product_7  | device_93 | pressure    |  62.177837 | 2023-01-21 14:52:45.494772+08
    gateway      | product_5  | device_1  | humidity    | 0.23014386 | 2023-01-21 14:51:14.290224+08
    others      | product_6  | device_61 | voltage     |  46.473114 | 2023-01-21 13:55:51.427582+08
    gateway      | product_4  | device_50 | pressure    |  53.413925 | 2023-01-21 10:11:41.670681+08
    actuator     | product_9  | device_13 | pressure    |  24.377035 | 2023-01-21 09:09:19.720012+08
    gateway      | product_3  | device_26 | current     |  58.887447 | 2023-01-21 07:38:12.482037+08
    gateway      | product_8  | device_82 | pressure    |  76.386024 | 2023-01-21 06:14:41.306756+08
    (10 rows)

    Получение последних 10 записей из таблицы iot_text

    =# SELECT * FROM iot_text ORDER BY ts DESC LIMIT 10;
    product_type |  product   |  device   | metric  |   value   |              ts
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    gateway      | product_10 | device_70 | status  | value_933 | 2023-01-21 22:03:51.85526+08
    others      | product_10 | device_46 | status  | value_471 | 2023-01-21 21:27:29.235879+08
    actuator     | product_4  | device_65 | log     | value_72  | 2023-01-21 21:20:27.515338+08
    gateway      | product_1  | device_34 | error   | value_864 | 2023-01-21 20:17:05.031651+08
    gateway      | product_6  | device_79 | warning | value_681 | 2023-01-21 18:03:51.699731+08
    actuator     | product_6  | device_92 | message | value_463 | 2023-01-21 17:51:20.218522+08
    gateway      | product_8  | device_44 | log     | value_526 | 2023-01-21 17:28:13.374733+08
    actuator     | product_4  | device_2  | warning | value_78  | 2023-01-21 16:52:34.770392+08
    sensor       | product_7  | device_49 | log     | value_258 | 2023-01-21 10:40:49.467672+08
    actuator     | product_7  | device_36 | error   | value_981 | 2023-01-21 08:05:55.809313+08
    (10 rows)
  2. Запрос общего количества строк в таблице iot_float
    =# SELECT COUNT(*) FROM iot_float;
    count
    -------
    100
    (1 row)

    Запрос общего количества строк в таблице iot_text

    =# SELECT COUNT(*) FROM iot_text;
    count
    -------
    100
    (1 row)
  3. Запрос всех последних показателей, переданных устройством, из таблицы iot_float
    =# SELECT * FROM iot_float WHERE device = 'device_1' ORDER BY ts DESC LIMIT 1;
    product_type |  product  |  device  |  metric  |   value    |              ts
    -----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    gateway      | product_5 | device_1 | humidity | 0.23014386 | 2023-01-21 14:51:14.290224+08
    (1 row)

    Запрос всех последних показателей, переданных устройством, из таблицы iot_text

    =# SELECT * FROM iot_text WHERE device = 'device_66' ORDER BY ts DESC LIMIT 1;
    product_type |  product  |  device   | metric |  value   |              ts
    -------------------------+--------------------------------------------------------------------------------------------------------
    others      | product_5 | device_66 | error  | value_94 | 2023-01-20 20:00:48.991428+08
    (1 row)

    Примечание!
    Здесь приведены только простые примеры тестов. Более подробные примеры тестирования различных сценариев см. в разделе графического интерфейса Лёгкое начало работы. В реальной среде разрабатывайте конкретные тестовые запросы в соответствии с фактическими требованиями к выборкам.