Learning Platform
Глоссарий Troubleshooting
Урок 05.03 · 25 мин
Начальный
SchemaEvolutionRegistry

Схемы: правила игры для данных

Схема — это контракт, как данные устроены: какие поля, какие типы, какие обязательны. Без схемы данные — хаос, никто не знает, что в них.

Но когда мы применяем схему — это фундаментальный вопрос в DE. Есть два подхода: schema-on-write и schema-on-read. От выбора зависит вся архитектура.


Что такое схема

Простой пример. Таблица orders:

CREATE TABLE orders (
  order_id     BIGINT       NOT NULL PRIMARY KEY,
  customer_id  BIGINT       NOT NULL,
  amount       DECIMAL(10,2) NOT NULL,
  status       VARCHAR(20)  NOT NULL,
  created_at   TIMESTAMP    NOT NULL DEFAULT now()
);

Здесь схема — это:

  • Структура: 5 колонок.
  • Типы: BIGINT, DECIMAL, VARCHAR, TIMESTAMP.
  • Constraints: NOT NULL, PRIMARY KEY, DEFAULT.

Если кто-то попытается записать amount = 'привет' или строку без customer_id, БД отклонит запись. Это и есть контракт.


Schema-on-write vs Schema-on-read

Schema-on-write vs Schema-on-read
Schema-on-write
Schema-on-read

Schema-on-write

«Сначала определи схему, потом пиши».

  • Postgres, MySQL, Snowflake, BigQuery — все DWH работают так.
  • При INSERT БД проверяет: тип правильный? NOT NULL поле не пустое? Constraints соблюдены?
  • Если нет — INSERT не проходит.

Плюсы:

  • Данные всегда валидны.
  • Аналитика работает: знаешь, что в колонке amount всегда число.
  • Performance: индексы и колоночное хранение работают.

Минусы:

  • Schema change — боль. Добавить колонку = ALTER TABLE, в большом DWH это часы.
  • Не для эволюционирующих источников: API меняется, схема устаревает.

Schema-on-read

«Пиши что есть, разберись потом».

  • Data Lake (S3), NoSQL (MongoDB), JSON-логи — все так.
  • Пишем JSON / файлы в любом формате.
  • При чтении (через SQL поверх Lake, например Athena / Snowflake EXTERNAL TABLES) применяем схему: «считай это JSON, поле user_id — INT».

Плюсы:

  • Гибкость — пиши что угодно.
  • Источник может менять схему — твой Lake это переживёт.
  • Cheap — S3 дёшев.

Минусы:

  • Data swamp — никто не знает, какие данные актуальны, как использовать.
  • Производительность ниже — парсинг при каждом чтении.
  • Без discipline — хаос.

Modern Data Stack: гибрид

Современный подход — гибрид:

Гибридный подход MDS
Bronze: schema-on-read (raw JSON)
Silver: schema-on-write (typed)
Gold: schema-on-write (final)

Идея:

  • Сырое — пиши как есть (schema-on-read). Если API изменится, ты ничего не теряешь.
  • На уровне staging — извлеки нужные поля, типизируй, дай схему.
  • На уровне marts — строгая схема для аналитики и BI.

Это даёт гибкость на входе и дисциплину на выходе.


Schema evolution

Источники меняются. Salesforce добавил поле, инженер добавил колонку в Postgres, маркетинг переименовал тег. Что делает твой pipeline?

Сценарии

Schema evolution: что бывает
Add column
Drop column
Type change
Rename column

Backward / Forward compatibility

В мире streaming (Kafka) важны два понятия:

  • Backward compatible — новые консьюмеры читают старые сообщения. Можно добавить optional поле.
  • Forward compatible — старые консьюмеры читают новые сообщения. Игнорируют новые поля.

Avro и Protobuf — оба supports эти концепции через schema rules.


Schema Registry

В streaming-мире (Kafka) есть отдельная сущность: Schema Registry. Это сервер, который хранит версии схем.

Schema Registry в Kafka
Producer
Schema Registry
Kafka topic
Consumer

Что даёт:

  • Версионирование схем — знаем, какая версия использовалась.
  • Compatibility checks — registry отклоняет breaking changes автоматически.
  • Эффективность — не нужно слать схему в каждом сообщении (Avro фишка).

Confluent Schema Registry — главный игрок. AWS Glue Schema Registry — конкурент. Apicurio — open-source.

Основы schema evolution: backward, forward, full compatibility

Schema Tests в dbt

В MDS схема валидируется тестами в dbt:

# models/schema.yml
version: 2
models:
  - name: stg_orders
    columns:
      - name: order_id
        tests:
          - not_null
          - unique
      - name: amount
        tests:
          - not_null
          - dbt_utils.expression_is_true:
              expression: ">= 0"
      - name: status
        tests:
          - accepted_values:
              values: ['pending', 'completed', 'cancelled']

Что это делает:

  • При dbt test запускает проверки на каждую колонку.
  • Если null там, где not_null — тест падает, алерт.
  • Если дубликаты в unique — тест падает.
  • Если новое status появилось — тест падает, ты узнаёшь сразу.

Это твоя страховка от schema changes в источнике.


Data Contracts — современный тренд

Современная идея: data contract между производителем данных и потребителем.

Data Contract
Producer Team (Backend)
Data Contract (YAML, Avro)
DE Team / Consumers
Analytics

Идея:

  • Producer (бэкенд-команда) обязан публиковать схему и SLA до того, как DE строит pipeline.
  • Breaking changes (rename, drop column) — только с согласия consumers.
  • Контракт версионируется в Git.

В 2024-2026 это активно растущий подход (Andrew Jones, Chad Sanderson). Инструменты: dbt contracts, GreatExpectations contracts, Datacontract-cli.

Зачем управлять схемами: Schema Registry в Kafka

Реальный пример эволюции схемы

Стартап, 2 года жизни:

Год 1 (MVP):

-- Postgres
CREATE TABLE users (id INT, email VARCHAR, created_at TIMESTAMP);

Год 2 (рост):

-- Postgres: добавили поля
ALTER TABLE users ADD COLUMN name VARCHAR;
ALTER TABLE users ADD COLUMN phone VARCHAR;
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMP;  -- soft delete

DE-pipeline:

  • Bronze (raw.users) — JSON через Fivetran, ловит новые поля автоматически.
  • Silver (stg_users) — нужно добавить новые колонки и retest.
  • Gold (mart.user_360) — обновить, чтобы использовать deleted_at.

Срыв:

В год 2 backend решил переименовать email -> email_address. Не предупредил.

Что произошло:

  • Fivetran подтянул новую колонку email_address.
  • Старая колонка email стала NULL для новых записей.
  • В Silver schema-test not_null on email упал. Алерт сработал.
  • DE поговорил с backend, добавил миграцию: COALESCE(email, email_address).

Без теста это попало бы в Gold, и аналитики получили бы пустые email. С тестом — поймали на staging.

Это и есть data contract в действии.


Что выбрать новичку

TIP

Базовое правило:

  • Сырое в Lake / Bronze — schema-on-read (просто JSON, без типов).
  • Staging / Silver — strict schema через dbt models + tests.
  • Mart / Gold — strict schema, дополнительные constraints.

И обязательно тесты на каждый слой. Без тестов schema changes тихо ломают пайплайн.


Попробуй сам

  1. Возьми любой публичный API (например, GitHub API на https://api.github.com/users/torvalds). Получи JSON. Подумай: какую schema-on-write ты бы спроектировал для DWH? Какие поля обязательны, какие — опциональны?

  2. Подумай: твоя любимая компания (например, банк, e-commerce). Какие могут быть breaking changes в схеме их данных, которые тихо сломают аналитику? Например, переименование статуса заказа.

Проверка знанийKnowledge check
Почему data contracts становятся всё более популярны как практика, особенно в крупных компаниях, где DE-команда находится отдельно от продуктовых команд?
ОтветAnswer
В крупных компаниях продуктовые команды (backend, mobile) часто меняют схемы данных без оглядки на потребителей: переименовывают колонки, удаляют поля, меняют типы — и это тихо ломает аналитику и ML-модели. DE команда узнаёт о breaking changes только когда что-то падает в проде (или, хуже, когда аналитики видят странные цифры). Data contracts формализуют отношения: producer (продуктовая команда) явно публикует схему и SLA как контракт, потребители (DE, analytics, ML) ссылаются на контракт, breaking changes требуют согласования и версионирования. Это перекладывает ответственность на producer (как с REST API в backend), создаёт ownership и видимость зависимостей. Без контрактов в большой компании любое изменение схемы — это игра в русскую рулетку с пайплайнами; с контрактами — это управляемый процесс со встроенными проверками.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. В чём ключевая разница между schema-on-write и schema-on-read?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4