Модуль 3.2. Семантика и справочники, DQ, MDM
Темы: глоссарий, домены данных, кодовые справочники, качество данных (валидность, полнота), мастер-данные. Сущности/атрибуты/ключи, справочники. Артефакты: глоссарий + спецификация справочников. Практика: выявить DQ-правила и метрики.
Системный аналитик данных (SA) отвечает за смысловую целостность домена: чтобы один и тот же термин в API, БД, отчёте и фронте означал одно и то же; чтобы коды и справочники были единообразны и версионируемы; чтобы качество данных (DQ) было измеряемым; чтобы мастер-данные (MDM) имели золотую запись и устойчивые ключи. В этом модуле соберём полный «скелет» семантики, DQ и MDM, с практикой и шаблонами.
Семантика: глоссарий и домены данных (как сотруднику — к исполнению)
Глоссарий = единый словарь
Цель: убрать двусмысленность. Каждый термин имеет:
- Определение (что это и что не это);
- Владельца (business/data steward);
- Источник правды (сервис/таблица);
- Атрибуты (имена, типы, домены);
- Статусы и правила переходов (если применимо);
- Синонимы/омонимы и «не путать с…».
Правило: первые упоминания терминов в SRS/ER/API — ссылаются на глоссарий. Имена полей ≡ терминам.
Домены данных
Домены задают тип + формат + допустимые значения/правила:
- Money: DECIMAL(18,2) + currency ISO4217, правило округления HALF_UP;
- Email: RFC-формат, уникальность по lower(email);
- OrderStatus: конечный автомат состояний;
- Country: ISO-коды, локализация названий.
Гигиена доменов
- Не прячьте домены в UI: валидируйте на границе API/БД.
- Домены живут в одном месте (shared schema/сервис справочников).
Справочники (Reference Data): типы, дизайн, версии
Что такое справочник
Небольшой, редко меняющийся набор кодов/значений, определяющий разрешённые состояния/категории:
- кодовые: order_status, payment_status, refund_reason;
- внешние коды: country, currency, document_type;
- иерархии: product_category (родитель-потомок);
- кросс-маппинги (crosswalk): соответствие внешних кодов внутренним.
Когда ENUM, когда таблица
- ENUM: крошечный и крайне стабильный перечень (например, Sex), локализация не требуется, нет версионирования дат.
- Таблица: всё остальное. Нужны эффективные даты, локализация, soft-delete/депрекация, иерархии, внешние ключи.
Спецификация справочника (что обязано быть)
- Идентификатор (PK, лучше числовой/UUID), код (человекочитаемый, уникальный), наименование (локализуемое).
- Семантика кода (не просто «строка»).
- Жизненный цикл: active/disabled/deprecated, valid_from, valid_to.
- Ссылочная целостность: FK из фактов на справочник + политика удаления (обычно RESTRICT).
- Версионирование и CHANGELOG (SemVer на схему + дата вступления).
- Локализация (таблица переводов).
- API/кеш: как читаем (TTL/ETag), как реагируем на «неизвестный код».
- Кросс-маппинги: таблица соответствий внешних кодов.
DDL-эскиз
CREATE TABLE ref_order_status ( status_id uuid PRIMARY KEY, code text NOT NULL UNIQUE, -- e.g. CREATED, PAID, SHIPPED name_default text NOT NULL, -- «Оплачен» description text, is_active boolean NOT NULL DEFAULT true, valid_from timestamptz NOT NULL DEFAULT now(), valid_to timestamptz, deprecated boolean NOT NULL DEFAULT false ); CREATE TABLE ref_order_status_i18n ( status_id uuid REFERENCES ref_order_status(status_id) ON DELETE CASCADE, locale text NOT NULL, -- ru-RU, en-US name text NOT NULL, description text, PRIMARY KEY (status_id, locale) ); -- Маппинг внешних кодов → внутренних CREATE TABLE map_order_status_external ( provider text NOT NULL, -- 'partnerA' ext_code text NOT NULL, status_id uuid NOT NULL REFERENCES ref_order_status(status_id), valid_from timestamptz NOT NULL DEFAULT now(), valid_to timestamptz, UNIQUE (provider, ext_code, valid_from) );
Контракт API справочника (минимум)
- GET /ref/order-status?active=true&at=2025-08-01
- Заголовки: ETag, Last-Modified, версия схемы.
- Поля: code, name, valid_from/to, deprecated, локали.
- Политика «неизвестного кода»: 422 с деталью какой код не принят; не превращайте в OTHER.
Качество данных (DQ): измеряем и управляем
Измерения качества
- Validity (валидность): значения соответствуют доменам/правилам.
- Completeness (полнота): обязательные поля заполнены.
- Uniqueness (уникальность): нет дубликатов (по ключам/правилам).
- Consistency (согласованность): одно и то же значение не противоречит в разных системах.
- Accuracy (точность): близость к реальности (часто проверяется выборками/вторичными источниками).
- Timeliness/Freshness (своевременность): задержка обновления.
- Integrity (целостность): FK/кардинальности, суммы/инварианты.
DQ-правила: «жёсткие» vs «мягкие»
- Hard: нарушил — транзакция отклонена (DB CHECK/NOT NULL/FK/UNIQUE).
- Soft: нарушил — запись принята, но событие/алерт/ремедиация (DQ-процесс).
Примеры DQ-правил (для домена «Заказы–Клиенты–Платежи»)
- Validity: currency ∈ ref_currency.active_at(t); email matches regex.
- Completeness: у Order при status=PAID обязательно paid_at и payment_id.
- Integrity: sum(order_items.amount) = order.total_amount.
- Uniqueness: LOWER(email) уникален в customer; payment.idempotency_key UNIQUE.
- Consistency: валюты Order и Payment совпадают; Refund.amount ≤ CapturedAmount.
- Freshness: orders_loaded_lag_minutes ≤ 15 для DWH витрины.
SQL-эскизы проверок
-- Полнота и валидность email
SELECT customer_id FROM customer
WHERE email IS NULL OR email !~* '^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$';
-- Целостность суммы заказа
SELECT o.order_id
FROM "order" o
JOIN order_item i USING (order_id)
GROUP BY o.order_id, o.total_amount
HAVING SUM(i.qty * i.price) <> o.total_amount;
-- Валюта платежа = валюте заказа
SELECT p.payment_id
FROM payment p JOIN "order" o ON o.order_id = p.order_id
WHERE p.currency <> o.currency;
-- Некорректные коды статусов
SELECT o.order_id, o.status
FROM "order" o LEFT JOIN ref_order_status s ON s.code = o.status AND s.is_active
WHERE s.status_id IS NULL;
DQ-метрики и SLO (пример формулировки)
DQ-COMP-ORDER-REQ: completeness_required_fields >= 99.9% per week DQ-UNIQ-CUST-EMAIL: duplicates_per_100k ≤ 2 DQ-VAL-CODE: invalid_code_rate(order.status) = 0 DQ-FRESH-ORDERS: freshness_lag_p95(minutes) ≤ 15 (08:00 daily)
Мониторинг/алерты: метрики в Prometheus (dq_invalid_code_total, dq_freshness_seconds), дашборды + оповещения (SEV-2/SEV-3).
Процесс DQ (governance)
- Каталог DQ-правил (в Git): owner, формула, SLO, способ проверки.
- Ежедневные прогоны (Airflow/dbt): отчёты нарушений + тикеты на ремедиацию.
- Трекинг трендов: снижение/рост дефектов.
- Гейты: релиз/миграция не проходит при нарушении критичных правил.
MDM (Master Data Management): мастер-данные, золотая запись
Что считаем мастер-данными
Стабильные, кросс-процессные сущности: Customer, Product, Supplier, иногда Location. Не путать с транзакциями (Order, Payment).
Подходы MDM
- Registry (реестр): хранит ссылки/идентификаторы, золотую запись собирает «налётом».
- Consolidation (консолидация): периодическая сборка золотой записи, источники остаются мастерами транзакций.
- Coexistence: часть атрибутов ведёт MDM, часть — источники.
- Centralized/Transaction: MDM — мастер и для контента, и для транзакций (дорого, редко оправдано).
Matching & Merging (сопоставление и слияние)
-
Матчинг: детерминированный (точные ключи: tax_id, email+phone) + вероятностный (фuzzy: name/address).
- Блокировки (blocking keys): soundex(name), first_letter + postal_code.
- Метрики сходства: Levenshtein/Jaro-Winkler, cosine на n-граммах.
- Мёрджинг (survivorship): правила «кто победит» для каждого атрибута:
- источник-лидер (prioritized source);
- «самое свежее» по updated_at;
- «не пустое» вместо NULL;
- «самое длинное» (для имен/адресов);
- «валидное по домену» (телефон с кодом страны).
Артефакты MDM
- Golden Record (идентификатор master_id + lineage атрибутов).
- Cross-ID Map: master_id ↔ {source, source_id}.
- События изменений: CustomerMasterUpdated с изменёнными полями.
- Стюард-процессы: ручная валидация конфликтов/слияний.
Ключи
- Master-ключ (master_id): суррогат, стабильный.
- Source-ключ: source_name + source_id.
-
Бизнес-ключи (natural): ИНН, email.
Правило: храните все типы ключей и карту соответствий.
SCD (медленно изменяющиеся атрибуты)
- Type 1 (перезапись): исправили опечатку в имени.
- Type 2 (история): смена адреса/сегмента — создаём новую версию с valid_from/to.
- Type 3 (предыдущее значение): редко, для аналитических задач.
Практические примеры (на домене из модуля 3.1)
Глоссарий (фрагмент)
Термин: Customer Определение: Лицо/организация, совершившее покупку хотя бы один раз. Источник правды: MDM.Customer (master_id), операционные источники — CRM, Checkout. Атрибуты: master_id, emails[], phones[], default_address_id, segment DQ: email уникален (case-insensitive), phone E.164, адрес с валидной страной. Термин: OrderStatus Определение: Статус жизненного цикла заказа; допустимые переходы см. state-модель. Домен: CREATED→PAID→SHIPPED→DELIVERED; ветка возвратов через CANCELLED/RETURN_REQUESTED. DQ: недопустимы коды вне ref_order_status.active_at(t).
Спецификация ключевых справочников
ref_order_status — см. DDL.
ref_payment_status: AUTHORIZED, CAPTURED, FAILED.
ref_refund_reason: коды «CUSTOMER_REQUEST», «DUPLICATE», «FRAUD_SUSPECTED» (эффективные даты + i18n).
ref_currency: ISO4217, флаги is_fiat, is_active, valid_from/to.
map_partner_status: кросс-маппинг статусов партнёра на наши.
DQ-правила и метрики (примерный набор)
- DQ-ORD-STATUS-VALID: invalid_code_rate(order.status) = 0.
- DQ-ORD-AMOUNT-CONSISTENT: доля заказов с расхождением суммы < 0.1%.
- DQ-CUST-EMAIL-UNIQ: duplicates_per_100k ≤ 2.
- DQ-PAY-IDEMPOTENT: дубликаты idempotency_key = 0.
- DQ-PAY-CURR-CONSISTENT: валютные несоответствия = 0.
- DQ-FRESH-ORDER-DWH: p95 лаг поступления в DWH ≤ 15 минут с 08:00 до 23:00.
Процессы и управление (governance)
Роли
- Data Owner (бизнес-владелец) — отвечает «что значит» и «как должно быть».
- Data Steward (стюард) — ведёт глоссарий/справочники/MDM-правила.
- SA (вы) — проектирует домены/ключи/ограничения/интеграции, формализует DQ/MDM.
- DBA/Данные инженеры — реализуют DDL, пайплайны, мониторинг.
- QA — автоматизирует DQ-тесты.
Изменения справочников
- CR с обоснованием, датами valid_from/to, обратной совместимостью, планом коммуникаций (release notes).
- Проверки: отсутствие «дыр», корректные маппинги, суммарное влияние на downstream.
- Катим через FF/канареечный список, TTL кэшей заранее снижаем.
Гейты качества
- Перед релизом схемы/миграций: «красные» DQ-правила = блокер.
- Еженедельный отчёт по метрикам DQ, тренды и план ремедиации.
Риски и как их гасить
-
ENUM-ловушка: понадобилась дата вступления/локализация — ENUM не масштабируется.
→ Перенос в реф-таблицу, миграция, адаптер для обратной совместимости. -
Коллизии кодов при интеграции с партнёрами.
→ Всегда неймспейс (prefix/provider), кросс-маппинг в отдельной таблице. -
Удаление кода c FK → каскадные «дыры» в фактах.
→ Не удаляйте, депрекируйте + valid_to, FK RESTRICT. -
Склейка разных клиентов (false positive) в MDM.
→ Консервативные пороги матчинга, ручная валидация, обратимость merge, хранение lineage. -
Дрейф значений (меняется семантика поля без объявления).
→ Контракты данных + тесты совместимости + release notes. -
Несогласованность валют/округлений.
→ Единые домены денег, правило округления, тесты инвариантов. -
Отсутствие freshness-контроля → отчёты «вчерашние».
→ Метрики лагов, алерты, SLA источников.
Вопрос–Ответ
Q: Чем справочник отличается от мастер-данных?
A: Справочник — небольшой и стабильный набор кодов/значений; мастер-данные — ключевые сущности с богатой структурой и жизненным циклом (Customer, Product).
Q: Когда выбирать Type 1, а когда Type 2 для атрибута?
A: Если важна история (адрес, сегмент) — Type 2; если это исправление ошибки (опечатка) — Type 1.
Q: Как обрабатывать неизвестный код в API?
A: Возвращать 422 с деталью. Никаких «OTHER»: это скрывает дефекты интеграции.
Q: Можно ли хранить названия статусов прямо в фактах?
A: Храните код в факте, а локализованные названия — в *_i18n. Так вы не «цементируете» язык в факте.
Q: Нужен ли MDM малому проекту?
A: Можно начать с «легкого» Registry + DQ-правила для уникальности; по мере роста — перейти к Consolidation.
Артефакты модуля (шаблоны — копируйте)
Шаблон записи в глоссарий (Markdown)
# <Термин> Owner: <ФИО> | Steward: <ФИО> | Source of Truth: <сервис/таблица> Определение: ... Не путать с: ... Синонимы: ... Атрибуты: - <attr>: <тип/домен/обязательность/валидаторы/пример> Статусы и переходы: <если применимо, ссылка на state-модель> DQ-правила: - <правило> (SLO: ..., проверка: ..., частота: ...) Связи: - ER: </docs/er/...> - API: </api/...> - Справочники: </docs/ref/...> Версии/Изменения: vX.Y.Z — ...
Шаблон «Спецификация справочника»
# Ref: <Название> (код: <ref_code>) vX.Y.Z Назначение: ... Схема: <БД/сервис>, Таблица: <имя>, API: GET /ref/<...> Поля: - id (uuid, PK) - code (string, UNIQUE, семантика: ...) - name_default (string) - description (string, optional) - is_active (bool) - valid_from (timestamptz), valid_to (timestamptz, nullable) Локализация: таблица <*_i18n>, поля: locale, name, description Иерархия: parent_id (nullable), ограничения: дерево без циклов Кросс-маппинг: таблица map_<ref>_external (provider, ext_code, valid_from/to) Границы совместимости: добавление кода — backwards compatible; удаление — запрещено, только deprecated+valid_to Кэш/ETag/TTL: ... Процесс изменения: CR→ревью(steward/SA/QA)→катка Тесты: coverage дыр/перекрытий, валидность кодов, маппинги
Шаблон «Карточка DQ-правила»
ID: DQ-<ДОМЕН>-NNN Название: <кратко> Владелец: <стейкхолдер>, Исполнитель: <команда> Тип: Validity/Completeness/Uniqueness/Consistency/Freshness/Integrity/Accuracy Описание: <человечески + формальное FEEL/SQL> SLO: <порог/окно>, Критичность: SEV-1/2/3 Источник: <таблицы/события> Метод проверки: SQL/dbt/GreatExpectations + расписание Метрика/экспорт: <PromQL/Graphite/лог-события> При нарушении: <автосоздание тикета, кого пейджить> История инцидентов/исправлений: ...
Шаблон «Правила матчинга/слияния MDM»
Сущность: Customer
Источники: {CRM, Checkout, Support}
Блокировки (blocking): {lower(email)}, {phone_digits_7}, {postal_code+first_letter}
Детерминированные ключи: tax_id, email+phone
Порог совпадения (prob.): 0.92 (Jaro-Winkler on name+address)
Survivorship:
- email: source priority {CRM > Checkout > Support}
- phone: most recent updated_at
- name: longest non-null
- address: valid_by_domain (E.164/ISO country), else manual review
Стюардство: спорные совпадения → очередь на ручной разбор в 24ч
События: CustomerMasterUpdated (diff, source lineage)
Практика: выявить DQ-правила и метрики (2–4 часа)
Вход: ваша ER-модель «Заказы–Клиенты–Платежи» (из модуля 3.1).
Задача: сформировать глоссарий (5–8 терминов), спецификацию 3–4 справочников и каталог DQ-правил (10–15) с метриками.
Шаги
- Глоссарий (5–8 терминов): Customer, Order, Payment, Refund, OrderStatus, Currency — по шаблону 9.1.
- Справочники (3–4): ref_order_status, ref_payment_status, ref_refund_reason, ref_currency — по шаблону 9.2.
- DQ-каталог (10–15 правил): минимум по одному из каждой категории (validity/completeness/uniqueness/consistency/freshness/integrity).
- Метрики и SLO: для каждого правила — формула и порог (см. 3.4).
- SQL/dbt-чек-и: для 5 правил — написать SQL-проверки.
- Мониторинг: описать экспорт метрик и алерты (названия метрик, порог, канал оповещения).
- MDM-набросок: определить мастер-сущность Customer: ключи, matching/survivorship (по шаблону 9.4).
Критерии зачёта
- Глоссарий полон, владельцы/источники указаны, термины однозначны.
- Справочники имеют valid_from/to, политику депрекации, кросс-маппинги.
- Не менее 10 DQ-правил с SLO и способами проверки; есть 5 SQL-чеков.
- MDM-набросок содержит блокировки, ключи, survivorship и процесс стюардства.
- Все артефакты версионированы и лежат в /docs (канон в Git, витрина — Confluence).
Рекомендованная структура репозитория
/docs /glossary/*.md /ref/ref_order_status.md /ref/ref_payment_status.md /ref/ref_refund_reason.md /ref/ref_currency.md /dq/catalog.md /dq/sql/checks.sql /mdm/customer-matching.md CHANGELOG.md
Шпаргалка (распечатайте)
- Глоссарий → домены → справочники — одна цепочка, живущая в Git.
- Справочник — таблица (почти всегда), с valid_from/to, i18n и кросс-маппингами.
- DQ = правила + метрики + алерты, а не только «проверки в голове».
- MDM: храните все ключи (master/source/natural), матчинг гибридный, merge обратимый.
- Никаких «OTHER/UNKNOWN» для скрытия дефектов интеграции — 422 с деталями.
- Деньги: DECIMAL + валюта + округление; статусы — конечные автоматы.
- Удалять коды нельзя — только депрекация и даты действия.
- Канон в Git, процесс изменений — через CR, ревью и тесты покрытий.



