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

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

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

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

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

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

2 Рекомендации по моделированию данных в умном доме

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

Шаг Действие
1 Сбор требований
2 Проектирование и реализация модели
3 Тестирование модели

2.1 Сбор требований

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

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

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

    • Объём данных: около 100 000 типов продуктов, каждый из которых имеет разное количество выпущенных устройств — обычно от 1 до 10 миллионов. Количество метрик на одно устройство, как правило, не превышает 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 <表名> ORDER BY ts DESC LIMIT 10
2 Запрос общего количества строк SELECT COUNT(*) FROM <表名>
3 Запрос всех последних метрик с определённого устройства SELECT * FROM <表名> WHERE <设备标签列名> = '<设备标签值>' ORDER BY <时间戳列名> 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)
  1. Подсчёт общего количества строк в таблице iot_float
=# SELECT COUNT(*) FROM iot_float;
count
-------
   100
(1 row)

Подсчёт общего количества строк в таблице iot_text

=# SELECT COUNT(*) FROM iot_text;
count
-------
   100
(1 row)
  1. Запрос всех последних метрик, отправленных определённым устройством, из таблицы 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)

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