---
title: 'Nivelul abstract de date'
section: 'Concepts'
weight: 2
description: Nivelul abstract de date, modelul de date unificat al sistemului, abstractizarea echipamentelor și normalizarea datelor, care decuplează aplicațiile de stocarea fizică.
related:
  - basic-modules/modules
  - data-representation/components
  - architecture/data-collection-layer
  - rest-api
---

Nivelul abstract de date se află între stocarea fizică a datelor și aplicațiile care le folosesc. Acesta ascunde implementarea fizică și particularitățile hardware și oferă o interfață unică pentru lucrul cu datele. Nivelul asigură:

- **Independență față de hardware**: datele sunt stocate pe dispozitive diferite (servere, cloud, dispozitive IoT), dar aplicația interacționează cu ele printr-o interfață unică.
- **Dezvoltare simplificată**: dezvoltatorii lucrează cu entități abstracte, fără să se preocupe de detaliile stocării fizice.
- **Flexibilitate**: modificările structurii fizice a datelor (de exemplu migrarea în cloud) nu afectează aplicațiile.

## Modelul de date unificat

Sistemul folosește un model de date unificat, adaptat la diferite tipuri de echipamente, care vă permite să lucrați uniform cu ele, indiferent de sursa datelor sau de tipul echipamentului. Modelul cuprinde structuri de date comune, reguli uniforme de prelucrare și coerența semantică a datelor în toate sistemele și componentele lor.

De exemplu, un model de date unificat al sistemului cuprinde:

- **Entități**: echipamente, canale, sesiuni, unități de măsură și parametri de nomenclator.
- **Relații**: echipamentele au canale, canalele sunt legate de date, iar datele sunt legate de sesiuni.
- **Atribute**: pentru fiecare entitate se definesc atribute (de exemplu `equipment.serial_number` și `channel_data.value`).

### Structura modelului de date unificat al sistemului

Modelul de date unificat al sistemului este o structură pentru stocarea și gestionarea datelor despre echipamente, canale, sesiuni și măsurări. Mai jos sunt descrise tabelele, rolul fiecăruia și relațiile dintre ele.

#### Tabelul `channel_data`

Acest tabel stochează datele primite de la canalele echipamentelor în cursul anumitor sesiuni.

| Câmp | Tip | Descriere |
| ----------------- | -------------------------------- | -------------------------------------------------- |
| `id` | `bigint` | Identificatorul unic al înregistrării (cheie primară). |
| `equipment_id` | `bigint` | Referință la echipament (`equipment.id`). |
| `seance_id` | `bigint` | Referință la sesiune (`seances.id`). |
| `channel_id` | `bigint` | Referință la canal (`channels.id`). |
| `unit_id` | `bigint` | Referință la unitatea de măsură (`units.id`). |
| `archive_type_id` | `integer` | Referință la tipul de arhivă (`referenceparameters.id`). |
| `event_time` | `integer` | Momentul evenimentului (de ex. marcă temporală). |
| `value` | `character varying(100)` | Valoarea primită de la canal. |
| `created_at` | `timestamp(6) without time zone` | Momentul creării înregistrării. |
| `updated_at` | `timestamp(6) without time zone` | Momentul ultimei actualizări a înregistrării. |

Relații:

- Cheia străină `unit_id` face referire la tabelul `units`.
- Cheia străină `archive_type_id` face referire la tabelul `referenceparameters`.
- Cheia străină `equipment_id` face referire la tabelul `equipment`.
- Cheia străină `channel_id` face referire la tabelul `channels`.
- Cheia străină `seance_id` face referire la tabelul `seances`.

#### Tabelul `units`

Acest tabel stochează unitățile de măsură folosite pentru datele canalelor.

| Câmp | Tip | Descriere |
| ------------------- | -------------------------------- | ------------------------------------------------ |
| `id` | `bigint` | Identificatorul unic al înregistrării (cheie primară). |
| `name` | `character varying(30)` | Denumirea unității de măsură. |
| `varname` | `character varying(30)` | Numele scurt de variabilă al unității de măsură. |
| `description` | `character varying(100)` | Descrierea unității de măsură. |
| `conversion_factor` | `double precision` | Factorul de conversie al unității de măsură. |
| `rounding` | `smallint` | Numărul de zecimale la care se rotunjește valoarea. |
| `synonyms` | `character varying[]` | Tablou de sinonime ale unității de măsură. |
| `created_at` | `timestamp(6) without time zone` | Momentul creării înregistrării. |
| `updated_at` | `timestamp(6) without time zone` | Momentul ultimei actualizări a înregistrării. |

#### Tabelul `referenceparameters`

Acest tabel stochează parametrii de nomenclator, de exemplu tipurile de arhive sau alți calificatori.

| Câmp | Tip | Descriere |
| ------------------- | -------------------------------- | ------------------------------------------------ |
| `id` | `bigint` | Identificatorul unic al înregistrării (cheie primară). |
| `name` | `character varying(30)` | Denumirea unității de măsură. |
| `varname` | `character varying(30)` | Numele scurt de variabilă al unității de măsură. |
| `description` | `character varying(100)` | Descrierea unității de măsură. |
| `parent_id` | `integer` | Referință la parametrul părinte (ierarhie). |
| `referencemodel_id` | `integer` | Referință la modelul nomenclatorului. |
| `created_at` | `timestamp(6) without time zone` | Momentul creării înregistrării. |
| `updated_at` | `timestamp(6) without time zone` | Momentul ultimei actualizări a înregistrării. |
| `deleted_at` | `timestamp(6) without time zone` | Momentul ștergerii logice (soft delete) a înregistrării. |

Relații:

- Cheia străină `parent_id` face referire la același tabel (`referenceparameters.id`), ceea ce permite construirea ierarhiilor.

#### Tabelul `equipment`

| Câmp | Tip | Descriere |
| ------------------- | -------------------------------- | ---------------------------------------------- |
| `id` | `bigint` | Identificatorul unic al înregistrării (cheie primară). |
| `equipment_type_id` | `bigint` | Referință la tipul de echipament. |
| `serial_number` | `character varying(25)` | Numărul de serie al echipamentului. |
| `manufacture_date` | `timestamp(6) without time zone` | Data fabricației echipamentului. |
| `installation_date` | `timestamp(6) without time zone` | Data instalării echipamentului. |
| `program_version` | `character varying(100)` | Versiunea de software a echipamentului. |
| `created_at` | `timestamp(6) without time zone` | Momentul creării înregistrării. |
| `updated_at` | `timestamp(6) without time zone` | Momentul ultimei actualizări a înregistrării. |

#### Tabelul `channels`

Acest tabel stochează informații despre canalele echipamentelor.

| Câmp | Tip | Descriere |
| ------------------- | -------------------------------- | ------------------------------------------------------ |
| `id` | `bigint` | Identificatorul unic al înregistrării (cheie primară). |
| `equipment_type_id` | `bigint` | Referință la tipul de echipament (`equipment_type.id`). |
| `unit_id` | `bigint` | Referință la unitatea de măsură (`units.id`). |
| `name` | `character varying(100)` | Denumirea canalului. |
| `varname` | `character varying(20)` | Numele scurt de variabilă al canalului. |
| `created_at` | `timestamp(6) without time zone` | Momentul creării înregistrării. |
| `updated_at` | `timestamp(6) without time zone` | Momentul ultimei actualizări a înregistrării. |

Relații:

- Cheia străină `equipment_type_id` face referire la tabelul `equipment_type`.
- Cheia străină `unit_id` face referire la tabelul `units`.

#### Tabelul `seances`

Acest tabel stochează informații despre sesiunile de comunicație ale echipamentelor.

| Câmp | Tip | Descriere |
| -------------- | -------------------------------- | ---------------------------------------------- |
| `id` | `bigint` | Identificatorul unic al înregistrării (cheie primară). |
| `telemetry_id` | `bigint` | Referință la telemetrie (`telemetry.id`). |
| `event_time` | `integer` | Momentul evenimentului. |
| `evtid` | `smallint` | Identificatorul evenimentului. |
| `trycnt` | `smallint` | Numărul de încercări. |
| `tryfl` | `character varying(12)` | Marcajul încercării. |
| `state` | `smallint` | Statusul sesiunii. |
| `btm` | `integer` | Starea de încărcare a bateriei. |
| `rssi` | `integer` | Puterea semnalului (dacă se folosește). |
| `created_at` | `timestamp(6) without time zone` | Momentul creării înregistrării. |
| `updated_at` | `timestamp(6) without time zone` | Momentul ultimei actualizări a înregistrării. |

#### Structura generală și relațiile

**Tabelul principal** – `channel_data`, care asociază datele canalelor cu echipamentele, sesiunile și unitățile de măsură.

**Tabele de legătură**:

- `units` – unități de măsură.
- `referenceparameters` – tipuri de arhive și alți calificatori.

**Tabelele echipamentelor**:

- `equipment` – informații despre echipamente.
- `channels` – canalele echipamentelor.

**Tabelul sesiunilor** – `seances`, care stochează informații despre sesiunile de comunicație.

**Exemplu de utilizare**:

- Datele canalelor (`channel_data`) provin de la echipamente (`equipment`) în cursul anumitor sesiuni (`seances`).
- Fiecare canal (`channels`) are propria unitate de măsură (`units`).
- Tipul de arhivă (`referenceparameters`) determină modul în care datele trebuie stocate sau prelucrate.

### Avantajele modelului unificat

Acest model de date oferă flexibilitatea și scalabilitatea necesare pentru stocarea și analiza datelor provenite de la echipamente diferite.

Printre avantajele unui model de date unificat se numără:

- **Coerență**: datele au aceeași structură și aceeași semantică în toate sistemele.
- **Scalabilitate**: se pot adăuga ușor noi surse de date sau noi tipuri de echipamente.
- **Protecția datelor**: mecanisme unificate de autentificare, autorizare și criptare.
- **Analiză simplificată**: datele pot fi analizate cu instrumente unificate.

## Abstractizarea echipamentelor

Abstractizarea echipamentelor, un principiu-cheie în proiectarea sistemului, separă logica de prelucrare a datelor de caracteristicile fizice ale echipamentelor. Acest lucru este deosebit de important în sistemele care folosesc dispozitive eterogene.

Abstractizarea echipamentelor înseamnă că sistemul lucrează cu datele la un nivel logic, independent de dispozitivele fizice pe care acestea sunt stocate sau prelucrate. Aceasta se obține prin:

- **Unificarea interfețelor**: un mod unic de acces la date, indiferent de echipament.
- **Ascunderea detaliilor de implementare**: locul fizic în care se află datele, protocoalele de transmisie și celelalte aspecte tehnice sunt ascunse aplicațiilor.
- **Adaptoare**: conversia datelor din formatul specific echipamentului într-un format unificat.

### Implementarea abstractizării echipamentelor

Exemplul de mai jos arată cum este implementată această abordare în sistemul nostru: datele pornesc de la un dispozitiv IoT, trec prin adaptor în modelul de date unificat și ies apoi prin API.

Să considerăm un dispozitiv IoT care transmite date despre consumul de gaze naturale. Algoritmii implementați permit:

- primirea datelor de la dispozitiv prin adaptor;
- conversia lor într-o structură `channel_data`;
- stocarea lor într-o bază de date;
- accesul la date prin API.

Pentru fiecare tip de echipament se creează adaptoare care tratează protocoalele specifice dispozitivului și convertesc datele într-un format unificat.

**Exemplu: transformarea datelor**

De la un dispozitiv IoT, datele pot sosi în format JSON:

```json title="example.json"
{
  "device_id": "sensor-123",
  "timestamp": 1739950861,
  "value": 42.5
}
```

Adaptorul convertește datele într-o structură `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);
```

Cererea de date:

```bash title="Request example"
GET /api/v1/channel_data?equipment_id=1&archive_type=daily&channel_id=3
```

Răspunsul:

```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
  }
]
```

### Avantajele abstractizării echipamentelor

- **Independență față de hardware**: aplicațiile lucrează cu datele fără să știe unde se află ele fizic.
- **Flexibilitate**: este ușor să adăugați dispozitive noi sau să le modificați pe cele existente.
- **Dezvoltare simplificată**: dezvoltatorii lucrează cu entități abstracte, fără să se preocupe de detaliile hardware.
- **Scalabilitate**: datele pot fi stocate pe dispozitive diferite, dar sistemul funcționează în continuare în mod uniform.

## Normalizarea datelor

Normalizarea datelor este procesul de organizare a datelor într-o bază de date astfel încât redundanța să fie minimă, iar integritatea datelor să crească. Pentru nivelul abstract de date, normalizarea are un rol-cheie în crearea unui model de date unificat și eficient, care poate fi folosit pentru lucrul cu diferite tipuri de echipamente și surse de date.

Normalizarea împarte datele în tabele logice și stabilește relații între ele pentru:

- eliminarea datelor duplicate;
- simplificarea administrării și a actualizării datelor;
- asigurarea integrității datelor;
- îmbunătățirea performanței interogărilor.

Modelul de date unificat al sistemului este adus la forma normală Boyce–Codd (a treia) în ceea ce privește valorile atomice (scalare). Unele entități ale modelului de date folosesc structuri compuse pentru a optimiza prelucrarea atributelor rare, nestandard.

### Avantajele normalizării

- **Elimină redundanța**: datele sunt stocate într-un singur loc, ceea ce reduce redundanța.
- **Coerența datelor**: menținerea coerenței datelor devine mai simplă.
- **Flexibilitate**: structura datelor se modifică ușor.
- **Performanță**: performanța interogărilor crește (în majoritatea cazurilor).

### Normalizarea în contextul nivelului abstract de date

Normalizarea datelor este o etapă importantă în proiectarea nivelului abstract de date.

Aceasta permite:

- crearea unui model de date unificat, care poate fi folosit pentru lucrul cu diferite tipuri de echipamente;
- eliminarea redundanței și a duplicării datelor;
- asigurarea integrității și a coerenței datelor, indiferent de sursa lor;
- simplificarea integrării noilor dispozitive și sisteme.
