---
title: 'Абстрактний рівень даних'
section: 'Concepts'
weight: 2
description: Абстрактний рівень даних, уніфікована модель даних системи, абстрагування обладнання та нормалізація даних, які відокремлюють застосунки від фізичного зберігання.
related:
  - basic-modules/modules
  - data-representation/components
  - architecture/data-collection-layer
  - rest-api
---

Абстрактний рівень даних розташований між фізичним зберіганням даних і застосунками, що їх використовують. Він приховує особливості фізичної реалізації та апаратного забезпечення, надаючи єдиний інтерфейс для роботи з даними. Він забезпечує:

- **Незалежність від апаратного забезпечення**: дані зберігаються на різних пристроях (серверах, у хмарі, на IoT-пристроях), але застосунок взаємодіє з ними через єдиний інтерфейс.
- **Спрощення розробки**: розробники працюють з абстрактними сутностями, не переймаючись подробицями фізичного зберігання.
- **Гнучкість**: зміни фізичної структури даних (наприклад, міграція до хмари) не впливають на застосунки.

## Уніфікована модель даних

Система використовує уніфіковану модель даних, яка адаптована до різних типів обладнання й дає змогу працювати з ними однаково, незалежно від джерела чи типу обладнання. Вона містить спільні структури даних, єдині правила обробки та семантичну узгодженість даних в усіх системах і підсистемах.

Наприклад, уніфікована модель даних системи містить:

- **Сутності**: обладнання, канали, сеанси, одиниці вимірювання та довідкові параметри.
- **Зв'язки**: обладнання має канали, канали пов'язані з даними, а дані пов'язані із сеансами.
- **Атрибути**: для кожної сутності визначено атрибути (наприклад, `equipment.serial_number` та `channel_data.value`).

### Структура уніфікованої моделі даних системи

Уніфікована модель даних системи — це структура для зберігання даних і керування ними, що пов'язані з обладнанням, каналами, сеансами та вимірюваннями. Розгляньмо кожну таблицю та її призначення, а також зв'язки між ними.

#### Таблиця `channel_data`

У цій таблиці зберігаються дані, отримані з каналів обладнання в межах конкретних сеансів.

| Поле              | Тип                              | Опис                                                |
| ----------------- | -------------------------------- | --------------------------------------------------- |
| `id`              | `bigint`                         | Унікальний ідентифікатор запису (первинний ключ).   |
| `equipment_id`    | `bigint`                         | Посилання на обладнання (`equipment.id`).           |
| `seance_id`       | `bigint`                         | Посилання на сеанс (`seances.id`).                  |
| `channel_id`      | `bigint`                         | Посилання на канал (`channels.id`).                 |
| `unit_id`         | `bigint`                         | Посилання на одиницю вимірювання (`units.id`).      |
| `archive_type_id` | `integer`                        | Посилання на тип архіву (`referenceparameters.id`). |
| `event_time`      | `integer`                        | Час події (наприклад, мітка часу).                  |
| `value`           | `character varying(100)`         | Значення, отримане з каналу.                        |
| `created_at`      | `timestamp(6) without time zone` | Час створення запису.                               |
| `updated_at`      | `timestamp(6) without time zone` | Час останнього оновлення запису.                    |

Зв'язки:

- Зовнішній ключ `unit_id` посилається на таблицю `units`.
- Зовнішній ключ `archive_type_id` посилається на таблицю `referenceparameters`.
- Зовнішній ключ `equipment_id` посилається на таблицю `equipment`.
- Зовнішній ключ `channel_id` посилається на таблицю `channels`.
- Зовнішній ключ `seance_id` посилається на таблицю `seances`.

#### Таблиця `units`

У цій таблиці зберігаються одиниці вимірювання, що використовуються для даних каналів.

| Поле                | Тип                              | Опис                                              |
| ------------------- | -------------------------------- | ------------------------------------------------- |
| `id`                | `bigint`                         | Унікальний ідентифікатор запису (первинний ключ). |
| `name`              | `character varying(30)`          | Назва одиниці вимірювання.                        |
| `varname`           | `character varying(30)`          | Коротка змінна назва одиниці вимірювання.         |
| `description`       | `character varying(100)`         | Опис одиниці вимірювання.                         |
| `conversion_factor` | `double precision`               | Коефіцієнт перетворення для одиниці вимірювання.  |
| `rounding`          | `smallint`                       | Кількість десяткових розрядів для округлення.     |
| `synonyms`          | `character varying[]`            | Масив синонімів одиниці вимірювання.              |
| `created_at`        | `timestamp(6) without time zone` | Час створення запису.                             |
| `updated_at`        | `timestamp(6) without time zone` | Час останнього оновлення запису.                  |

#### Таблиця `referenceparameters`

У цій таблиці зберігаються довідкові параметри, як-от типи архівів чи інші кваліфікатори.

| Поле                | Тип                              | Опис                                              |
| ------------------- | -------------------------------- | ------------------------------------------------- |
| `id`                | `bigint`                         | Унікальний ідентифікатор запису (первинний ключ). |
| `name`              | `character varying(30)`          | Назва одиниці вимірювання.                        |
| `varname`           | `character varying(30)`          | Коротка змінна назва одиниці вимірювання.         |
| `description`       | `character varying(100)`         | Опис одиниці вимірювання.                         |
| `parent_id`         | `integer`                        | Посилання на батьківський параметр (ієрархія).    |
| `referencemodel_id` | `integer`                        | Посилання на модель довідника.                    |
| `created_at`        | `timestamp(6) without time zone` | Час створення запису.                             |
| `updated_at`        | `timestamp(6) without time zone` | Час останнього оновлення запису.                  |
| `deleted_at`        | `timestamp(6) without time zone` | Час видалення запису (м'яке видалення).           |

Зв'язки:

- Зовнішній ключ `parent_id` посилається на ту саму таблицю (`referenceparameters.id`), що дає змогу будувати ієрархії.

#### Таблиця `equipment`

| Поле                | Тип                              | Опис                                              |
| ------------------- | -------------------------------- | ------------------------------------------------- |
| `id`                | `bigint`                         | Унікальний ідентифікатор запису (первинний ключ). |
| `equipment_type_id` | `bigint`                         | Посилання на тип обладнання.                      |
| `serial_number`     | `character varying(25)`          | Серійний номер обладнання.                        |
| `manufacture_date`  | `timestamp(6) without time zone` | Дата виготовлення обладнання.                     |
| `installation_date` | `timestamp(6) without time zone` | Дата встановлення обладнання.                     |
| `program_version`   | `character varying(100)`         | Версія програмного забезпечення обладнання.       |
| `created_at`        | `timestamp(6) without time zone` | Час створення запису.                             |
| `updated_at`        | `timestamp(6) without time zone` | Час останнього оновлення запису.                  |

#### Таблиця `channels`

У цій таблиці зберігається інформація про канали обладнання.

| Поле                | Тип                              | Опис                                               |
| ------------------- | -------------------------------- | -------------------------------------------------- |
| `id`                | `bigint`                         | Унікальний ідентифікатор запису (первинний ключ).  |
| `equipment_type_id` | `bigint`                         | Посилання на тип обладнання (`equipment_type.id`). |
| `unit_id`           | `bigint`                         | Посилання на одиницю вимірювання (`units.id`).     |
| `name`              | `character varying(100)`         | Назва каналу.                                      |
| `varname`           | `character varying(20)`          | Коротка змінна назва каналу.                       |
| `created_at`        | `timestamp(6) without time zone` | Час створення запису.                              |
| `updated_at`        | `timestamp(6) without time zone` | Час останнього оновлення запису.                   |

Зв'язки:

- Зовнішній ключ `equipment_type_id` посилається на таблицю `equipment_type`.
- Зовнішній ключ `unit_id` посилається на таблицю `units`.

#### Таблиця `seances`

У цій таблиці зберігається інформація про сеанси зв'язку обладнання.

| Поле           | Тип                              | Опис                                              |
| -------------- | -------------------------------- | ------------------------------------------------- |
| `id`           | `bigint`                         | Унікальний ідентифікатор запису (первинний ключ). |
| `telemetry_id` | `bigint`                         | Посилання на телеметрію (`telemetry.id`).         |
| `event_time`   | `integer`                        | Час події.                                        |
| `evtid`        | `smallint`                       | Ідентифікатор події.                              |
| `trycnt`       | `smallint`                       | Кількість спроб.                                  |
| `tryfl`        | `character varying(12)`          | Прапорець спроби.                                 |
| `state`        | `smallint`                       | Стан сеансу.                                      |
| `btm`          | `integer`                        | Заряд акумулятора.                                |
| `rssi`         | `integer`                        | Рівень сигналу (якщо використовується).           |
| `created_at`   | `timestamp(6) without time zone` | Час створення запису.                             |
| `updated_at`   | `timestamp(6) without time zone` | Час останнього оновлення запису.                  |

#### Загальна структура та зв'язки

**Основна таблиця** — `channel_data`, яка пов'язує дані каналів з обладнанням, сеансами та одиницями вимірювання.

**Таблиці зв'язків**:

- `units` — одиниці вимірювання.
- `referenceparameters` — типи архівів та інші кваліфікатори.

**Таблиці обладнання**:

- `equipment` — інформація про обладнання.
- `channels` — канали обладнання.

**Таблиця сеансів** — `seances`, у якій зберігається інформація про сеанси зв'язку.

**Приклад використання**:

- Дані каналів (`channel_data`) надходять від обладнання (`equipment`) у межах конкретних сеансів (`seances`).
- Кожен канал (`channels`) має власну одиницю вимірювання (`units`).
- Тип архіву (`referenceparameters`) визначає, як саме слід зберігати чи обробляти дані.

### Переваги уніфікованої моделі

Ця модель даних забезпечує гнучкість і масштабованість для зберігання та аналізу даних з різного обладнання.

Серед переваг уніфікованої моделі даних:

- **Узгодженість**: дані мають однакову структуру та семантику в усіх системах.
- **Масштабованість**: легко додавати нові джерела даних чи типи обладнання.
- **Захист даних**: єдині механізми автентифікації, авторизації та шифрування.
- **Спрощення аналізу**: дані можна аналізувати за допомогою єдиних інструментів.

## Абстрагування обладнання

Абстрагування обладнання — це ключовий принцип проєктування системи, який відокремлює логіку обробки даних від фізичних характеристик обладнання. Це особливо важливо в системах, що використовують різнорідні пристрої.

Абстрагування обладнання означає, що система обробляє дані на логічному рівні, незалежному від фізичних пристроїв, на яких дані зберігаються чи обробляються. Це досягається завдяки:

- **Уніфікації інтерфейсів**: єдиний спосіб доступу до даних, незалежно від обладнання.
- **Приховуванню подробиць реалізації**: фізичне розташування даних, протоколи передавання та інші технічні аспекти приховані від застосунків.
- **Адаптерам**: перетворення даних із формату, специфічного для обладнання, в уніфікований формат.

### Реалізація абстрагування обладнання

Наведений приклад показує, як цей підхід реалізовано в нашій системі. Він простежує шлях даних від IoT-пристрою через адаптер до уніфікованої моделі даних і назовні через API.

Розгляньмо IoT-пристрій, який надсилає дані про споживання газу. Реалізовані алгоритми дають нам змогу:

- Отримувати дані від пристрою через адаптер.
- Перетворювати їх на структуру `channel_data`.
- Зберігати їх у базі даних.
- Надавати доступ до даних через API.

Для кожного типу обладнання створюються адаптери, які обробляють специфічні для пристрою протоколи й перетворюють дані в уніфікований формат.

**Приклад: перетворення даних**

Для IoT-пристрою дані можуть надходити у форматі JSON:

```json title="example.json"
{
  "device_id": "sensor-123",
  "timestamp": 1739950861,
  "value": 42.5
}
```

Адаптер перетворює дані на структуру `channel_data`:

```sql title="example.sql"
INSERT INTO channel_data (equipment_id, seance_id, channel_id,
 archive_type_id, value, event_time)
VALUES (1, 2, 3, 4, '42.5', 1739950861);
```

Запит даних:

```bash title="Request example"
GET /api/v1/channel_data?equipment_id=1&archive_type=daily&channel_id=3
```

Відповідь:

```json title="Response example"
[
  {
    "id": 123,
    "equipment_id": 1,
    "seance_id": 2,
    "channel_id": 3,
    "archive_type_id": 4,
    "value": 42.5,
    "event_time": 1739950861
  }
]
```

### Переваги абстрагування обладнання

- **Незалежність від апаратного забезпечення**: застосунки працюють з даними, не знаючи, де вони фізично розташовані.
- **Гнучкість**: легко додавати нові пристрої чи змінювати наявні.
- **Спрощення розробки**: розробники працюють з абстрактними сутностями, не переймаючись подробицями апаратного забезпечення.
- **Масштабованість**: дані можна зберігати на різних пристроях, але система продовжує працювати однаково.

## Нормалізація даних

Нормалізація даних — це процес упорядкування даних у базі даних у спосіб, що мінімізує надлишковість і підвищує цілісність даних. У контексті абстрактного рівня даних нормалізація відіграє ключову роль у створенні уніфікованої, ефективної моделі даних, яку можна використовувати для обробки різних типів обладнання та джерел даних.

Нормалізація даних поділяє дані на логічні таблиці й установлює зв'язки між ними, щоб:

- Усунути дублювання даних.
- Спростити супровід та оновлення даних.
- Забезпечити цілісність даних.
- Підвищити продуктивність запитів.

Уніфіковану модель даних системи приведено до (третьої) нормальної форми Бойса — Кодда в частині атомарних (скалярних) значень. Деякі сутності моделі даних використовують складені структури для оптимізації обробки рідкісних, нестандартних атрибутів.

### Переваги нормалізації

- **Усунення надлишковості**: дані зберігаються в одному місці, що зменшує надлишковість.
- **Узгодженість даних**: підтримання узгодженості даних спрощується.
- **Гнучкість**: легко вносити зміни до структури даних.
- **Продуктивність**: продуктивність запитів підвищується (у більшості випадків).

### Нормалізація в контексті абстрактного рівня даних

Нормалізація даних — це важливий крок у проєктуванні абстрактного рівня даних.

Вона дає змогу:

- Створити уніфіковану модель даних, яку можна використовувати для обробки різних типів обладнання.
- Усунути надлишковість і дублювання даних.
- Забезпечити цілісність та узгодженість даних, незалежно від їхнього джерела.
- Спростити інтеграцію нових пристроїв і систем.
