Перейти к содержанию

Качество данных — зачем и как проверять

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


Что бывает без проверок

Проблема в данных Последствие
Дубликаты заказов Выручка в отчёте завышена в 2 раза
NULL в поле region Дашборд показывает пустую карту
Статус 'test' в продуктовых данных Метрики конверсии искажены
Данные не обновились за сутки Аналитик строит прогноз на вчерашних числах
Цена = −100 Финансовый отчёт уходит в минус

Стоимость ошибки растёт по цепочке

Ошибка в staging-таблице → неправильный расчёт в intermediate → искажённая витрина → неверный дашборд → бизнес-решение на плохих данных. Чем раньше поймаешь — тем дешевле исправить.


6 измерений качества данных

Data Management Body of Knowledge (DMBOK) выделяет шесть ключевых измерений. Каждое отвечает на свой вопрос о данных.

1. Completeness — полнота

Вопрос: Все ли данные на месте?

Проверяешь, что обязательные поля заполнены и нет пропущенных записей.

SQL
-- Сколько заказов без региона?
SELECT COUNT(*) AS missing_region
FROM orders
WHERE region IS NULL;
missing_region
342

Проверяй не только NULL

Пустая строка '', значение 'N/A' или 'unknown' — тоже пропуски. WHERE region IS NULL OR region = '' OR region = 'N/A'.

2. Accuracy — точность

Вопрос: Данные соответствуют реальности?

Проверяешь, что значения правдоподобны и попадают в допустимый диапазон.

SQL
-- Есть ли заказы с отрицательной ценой?
SELECT order_id, total_amount
FROM orders
WHERE total_amount < 0;
order_id total_amount
98431 −100.00
SQL
-- Возраст пользователей в разумном диапазоне?
SELECT user_id, age
FROM users
WHERE age < 0 OR age > 150;

3. Consistency — согласованность

Вопрос: Одни и те же данные не противоречат друг другу?

Проверяешь, что связанные таблицы и поля не конфликтуют.

SQL
-- Заказы, где дата доставки раньше даты создания
SELECT order_id, created_at, delivered_at
FROM orders
WHERE delivered_at < created_at;
SQL
-- Сумма позиций не совпадает с итогом заказа
SELECT
  o.order_id,
  o.total_amount AS order_total,
  SUM(oi.qty * oi.price) AS calculated_total
FROM orders o
JOIN order_items oi ON o.order_id = oi.order_id
GROUP BY o.order_id, o.total_amount
HAVING o.total_amount != SUM(oi.qty * oi.price);

4. Timeliness — своевременность

Вопрос: Данные достаточно свежие?

Проверяешь, что ETL-процессы работают и данные обновляются вовремя.

SQL
-- Когда последний раз обновлялась таблица?
SELECT MAX(updated_at) AS last_update
FROM orders;
last_update
2026-03-31 08:15:00

Если сейчас 2 апреля — данные отстают на 2 дня. Это проблема.

Source freshness в dbt

dbt умеет автоматически проверять свежесть источников через dbt source freshness. Настраиваешь пороги warn_after и error_after — dbt сам сообщит, если данные устарели.

5. Validity — валидность

Вопрос: Данные соответствуют формату и правилам?

Проверяешь, что значения из допустимого множества, форматы корректны.

SQL
-- Статусы, которых не должно быть
SELECT DISTINCT status
FROM orders
WHERE status NOT IN ('paid', 'pending', 'cancelled', 'refunded');
status
test
PAID
SQL
-- Email без @ — невалидный формат
SELECT user_id, email
FROM users
WHERE email NOT LIKE '%@%.%';

6. Uniqueness — уникальность

Вопрос: Нет ли дубликатов?

Проверяешь, что первичные ключи действительно уникальны.

SQL
-- Дубликаты order_id
SELECT order_id, COUNT(*) AS cnt
FROM orders
GROUP BY order_id
HAVING COUNT(*) > 1;
order_id cnt
12345 3
67890 2

Дубликаты — самая частая проблема

Неправильный JOIN, повторная загрузка, отсутствие дедупликации — всё это создаёт дубли. Тест unique на первичный ключ — обязательный минимум для каждой таблицы.


Обзор измерений

Измерение Вопрос Типичная проверка
Completeness Всё ли на месте? NOT NULL, подсчёт пропусков
Accuracy Данные правдивы? Диапазоны значений, сравнение с источником
Consistency Нет противоречий? Сравнение связанных таблиц и полей
Timeliness Данные свежие? Проверка MAX(updated_at), source freshness
Validity Формат корректен? Допустимые значения, regex
Uniqueness Нет дубликатов? GROUP BY ... HAVING COUNT(*) > 1

Инструменты проверки качества

dbt tests

Встроенные тесты dbt — самый простой способ начать. Четыре теста «из коробки» покрывают базовые проверки:

YAML
models:
  - name: stg_orders
    columns:
      - name: order_id
        tests:
          - unique
          - not_null
      - name: status
        tests:
          - accepted_values:
              values: ['paid', 'pending', 'cancelled', 'refunded']
      - name: user_id
        tests:
          - relationships:
              to: ref('stg_users')
              field: user_id

Плюсы: интегрирован в dbt-пайплайн, нулевая настройка, YAML-конфигурация. Минусы: только SQL-проверки, нет профилирования данных, ограниченная отчётность.

Great Expectations (GX)

Фреймворк для валидации данных на Python. Expectations — декларативные правила, которые можно применять к DataFrame, SQL-таблице или файлу.

Python
import great_expectations as gx

context = gx.get_context()
validator = context.sources.pandas_default.read_csv("orders.csv")

validator.expect_column_values_to_not_be_null("order_id")
validator.expect_column_values_to_be_between("total_amount", min_value=0)
validator.expect_column_values_to_be_in_set(
    "status", ["paid", "pending", "cancelled", "refunded"]
)

results = validator.validate()

Плюсы: 300+ встроенных expectations, Data Docs (автодокументация), интеграция с Airflow. Минусы: сложная настройка, Python-зависимость, тяжёлый для небольших проектов.

Soda

Инструмент мониторинга данных с YAML-конфигурацией и облачным дашбордом.

YAML
# checks/orders.yml
checks for orders:
  - row_count > 0
  - missing_count(order_id) = 0
  - duplicate_count(order_id) = 0
  - invalid_count(status) = 0:
      valid values: ['paid', 'pending', 'cancelled', 'refunded']
  - freshness(updated_at) < 24h

Плюсы: простой YAML-синтаксис, встроенная проверка свежести, облачный мониторинг. Минусы: облачная версия платная, меньше гибкости чем GX.

Сравнение инструментов

Критерий dbt tests Great Expectations Soda
Язык проверок YAML + SQL Python YAML
Встроенных проверок 4 (+ пакеты) 300+ 25+
Интеграция с dbt Нативная Через пакет Через CLI
Отчётность Терминал Data Docs (HTML) Облачный дашборд
Порог входа Низкий Средний Низкий
Стоимость Бесплатно Бесплатно (OSS) Freemium
Лучше всего для dbt-проекты Python-пайплайны Мониторинг в проде

Как выбрать подход

Text Only
Есть dbt-проект?
├── Да → Начни с dbt tests (unique, not_null, accepted_values)
│         Нужно больше? → Добавь dbt-expectations (пакет с 50+ тестами)
│         Нужен мониторинг? → Подключи Soda или Elementary
└── Нет
    ├── Python-пайплайн → Great Expectations
    └── Нужен быстрый мониторинг → Soda

Начни с малого

Не пытайся покрыть тестами всё сразу. Начни с трёх проверок на каждую ключевую таблицу: unique на PK, not_null на обязательные поля, accepted_values на статусы. Остальное добавляй по мере обнаружения проблем.


Что запомнить

  • 6 измерений качества: полнота, точность, согласованность, своевременность, валидность, уникальность
  • Каждое измерение — конкретная SQL-проверка, которую можно автоматизировать
  • dbt tests — минимальный порог входа, встроен в пайплайн
  • Great Expectations — мощный фреймворк для Python-стека
  • Soda — мониторинг с YAML и облачным дашбордом
  • Начни с unique + not_null на ключевые таблицы — это уже лучше, чем ничего

Проверь себя


Что дальше?

Теперь, когда ты понимаешь что проверять, разберись с Great Expectations — как настроить автоматическую валидацию данных на Python.


Источники