Форматы представления данных в ВКР: как нотация экономит месяцы интеграции
Статья о римских цифрах, узелках инков и букве «x» на ценнике бьёт в неожиданную для ИТ точку: цивилизации веками упирались не в отсутствие талантливых математиков, а в неудачный способ записи. Непозиционная система без нуля делает деление мучительным, а узелковое письмо кипу отлично хранит учёт, но плохо поддаётся формальным преобразованиям. Буква «x» в современном магазине — окаменевший след римской десятки, доживший до наших дней как курьёз.
Для выпускника направления Data Engineering вывод прямой: формат хранения и описания данных определяет, что вы сможете автоматизировать, а что будете делать руками до конца проекта. Пока в вашей системе дата лежит в трёх видах, сумма — то строкой, то float, а идентификатор клиента — то int, то e-mail, любая аналитика превращается в римскую арифметику. Ниже — как превратить этот тезис в защищаемую ВКР, а не в эссе по истории науки.
Основная часть: от тезиса статьи к трём темам и измеримому результату
Тема 1. Каноническая модель данных и словарь нотаций для интеграционной шины
Актуальность (след из статьи): каждая подсистема пишет «одно и то же» по-своему — ровно как римлянин и инка считали одинаковые величины разными знаками. Стоимость стыковки растёт не из-за алгоритмов, а из-за отсутствия общего канона записи. В статье это показано на тысячелетиях, у вас — на трёх системах вуза или отдела.
- Цель: сократить трудозатраты на подключение нового источника к шине за счёт единой канонической модели и правил именования.
- Задачи: инвентаризация источников и их «диалектов»; обзор нотаций (ER, UML class, JSON Schema, Avro IDL); разработка канона и справочника полей; реализация маппинга источник → канон; замер трудозатрат до/после.
- Гл. 1: анализ предметной области, разбор нотаций, обоснование выбора по ISO/IEC 25010 (функциональная пригодность, сопровождаемость).
- Гл. 2: C4-диаграммы контейнеров, ER-модель канона, контракты данных, маппинг-слой.
- Гл. 3: пилот на 2–3 источниках, метрики, сравнение сценария «без канона» и «с каноном».
Тема 2. Сравнительная оценка форматов сериализации для аналитического хранилища
Актуальность: выбор JSON «потому что удобно», XML «потому что так исторически» или Parquet «потому что модно» без замеров — это ровно позиция писца, которому привычны римские цифры. Нужен эксперимент, а не вкусовщина.
- Цель: выбрать формат обмена и хранения по многокритериальной оценке, а не по привычке.
- Задачи: сформировать репрезентативный набор данных; реализовать сериализацию/десериализацию в 4 форматах; замерить объём, время, поведение при эволюции схемы; свести результаты в матрицу выбора.
- Гл. 1: теория: текстовые vs бинарные форматы, row vs column-oriented, схема-он-записи vs схема-при-чтении.
- Гл. 2: стенд, генератор данных, скрипты замеров, схема эксперимента (одинаковое железо, одинаковый объём).
- Гл. 3: p50/p95 времени, сжатие, стоимость миграции поля, вывод-рекомендация.
Тема 3. Идентификация сущностей: стратегии ключей в распределённой системе
Актуальность: отсутствие нуля в римской нотации — это, по сути, отсутствие корректного «пустого идентификатора». В вашей системе ту же роль играет отсутствие единой стратегии ID: автоинкремент в одной базе, UUID в другой, «код по справочнику» в третьей. Дальше — дубли, битые связи, ручные сверки.
- Цель: обосновать стратегию идентификации, устойчивую к слиянию источников.
- Задачи: классифицировать сущности (естественные/суррогатные ключи); сравнить UUIDv4, UUIDv7, ULID и составные ключи; замерить размер индекса и скорость вставки; описать миграцию.
| Тема | Гл. 1 — анализ | Гл. 2 — проектирование и реализация | Гл. 3 — эффект |
|---|---|---|---|
| Каноническая модель | Обзор нотаций, ISO/IEC 25010, ГОСТ 34.602 (ТЗ) | C4 + ER, контракты данных, маппинг | Часы на подключение источника, число ручных правок |
| Форматы сериализации | JSON / XML / Protobuf / Avro / Parquet, schema evolution | Стенд, генератор данных, скрипты замеров | p50/p95, объём на диске, число сломанных контрактов |
| Стратегии ключей | Естественные и суррогатные ключи, коллизии | Генераторы ID, схема миграции, индексы | Размер индекса, скорость вставки, дубли |
Что перенести из статьи в первую главу, чтобы её не назвали «рефератом»
Не пересказывайте историю математики. Возьмите из материала три опоры и разверните их в инженерные критерии:
- Позиционность vs непозиционность → зависимость смысла от позиции и контекста → в данных это явные и неявные схемы, порядок полей, разделители, локали. Отсюда требование: схема должна быть машинночитаемой, а не «понятной по названию колонки».
- Отсутствие нуля как тормоз → отсутствие явного значения «неизвестно» (NULL, sentinel-значения, пустые строки) ломает агрегаты. Сразу вводите политику обработки пропусков и фиксируйте её в контракте.
- Узелковое письмо кипу → данные можно хранить, но нельзя дешево преобразовывать, если нет формальной грамматики. В ВКР это аргумент в пользу JSON Schema / Avro вместо «договоримся на словах».
Хороший ход на защите — мини-таблица соответствия: «историческая нотация → современный аналог проблемы → принятое в проекте решение». Она показывает, что источник осмыслен, а не приклеен для актуальности.
Глава 2: проектирование канона и контракта данных
Каркас решения опишите диаграммой C4 (уровень контейнеров) и одной ER-моделью. Словами поток выглядит так:
Источник A ─┐
Источник B ─┼─► [raw-слой] ─► [канонизация] ─► [контракт данных] ─► витрины
Источник C ─┘ как есть маппинг + JSON Schema / BI, API
валидация Avro + версия
Схему канона фиксируйте формально — иначе защита превращается в спор о вкусах. Минимальный контракт на JSON Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.ru/schemas/contract.v1.json",
"title": "Contract",
"type": "object",
"additionalProperties": false,
"required": ["contract_id", "signed_at", "amount_minor", "currency"],
"properties": {
"contract_id": { "type": "string", "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$" },
"signed_at": { "type": "string", "format": "date-time" },
"amount_minor":{ "type": "integer", "description": "сумма в минорных единицах" },
"currency": { "type": "string", "enum": ["RUB", "USD", "EUR"] }
}
}
Обратите внимание на два защищаемых решения: amount_minor как целое (никаких float для денег — прямой аналог «записи, которая портит вычисление») и жёсткий additionalProperties: false (контракт ломается явно и на входе, а не тихо на витрине).
Для потоковой части тот же канон в Avro — с default, чтобы читатели пережили добавление поля:
{
"type": "record",
"name": "Contract",
"namespace": "ru.example.contracts",
"fields": [
{"name": "contract_id", "type": "string"},
{"name": "signed_at", "type": {"type": "long", "logicalType": "timestamp-micros"}},
{"name": "amount_minor", "type": "long"},
{"name": "currency", "type": "string", "default": "RUB"}
]
}
Правило совместимости пропишите в Гл. 2 текстом: добавлять поля — только с default; переименовывать — через alias; удалять — через депрекацию на два релиза. Это и есть ваш «позиционный принцип» в действии.
Глава 3: как считать эффект, а не «стало удобнее»
Комиссия любит один вопрос: «Насколько лучше?» Готовьте базу сравнения — те же данные, то же железо, пять прогонов, p50 и p95. Минимальный набор метрик:
| Группа | Метрика | Как получить |
|---|---|---|
| Качество данных | Полнота, уникальность, валидность, своевременность | SQL-проверки по слою raw и по канону (опирайтесь на практики DAMA-DMBOK) |
| Производительность | p50/p95 сериализации, объём на диске | Скрипт-бенчмарк, одинаковый датасет |
| Сопровождаемость | Время на добавление поля, число сломанных контрактов | Журнал задач пилота + результаты проверки совместимости |
| Трудозатраты | Часы на подключение нового источника | Хронометраж до/после внедрения канона |
Проверка полноты и уникальности — четыре строки SQL, которые на защите выглядят убедительнее десяти слайдов:
SELECT
COUNT(*) FILTER (WHERE contract_id IS NULL)::numeric / COUNT(*) AS completeness_gap,
COUNT(DISTINCT contract_id)::numeric / COUNT(*) AS uniqueness_ratio,
COUNT(*) FILTER (WHERE amount_minor IS NULL)::numeric / COUNT(*) AS amount_gap
FROM dwh.contract_raw
WHERE load_dt = current_date - 1;
И псевдокод канонизации, где валидация стоит до записи, а не в отчёте на следующий день:
def to_canonical(raw, mapping, schema):
row = {target: extract(raw, path) for target, path in mapping.items()}
row["amount_minor"] = int(Decimal(raw["amount"]) * 100) # без float
validate(row, schema) # падаем на входе
return row
Дополнительный плюс — трассировка происхождения полей (data lineage). Достаточно таблицы «поле канона → источник → правило преобразования» в приложении; в тексте сошлитесь на подход OpenLineage как на ориентир, не более.
Чему вы научитесь на такой ВКР
- Формализовать «диалекты» источников в контракт данных и защищать его как инженерное решение, а не как картинку.
- Обосновывать выбор формата сериализации замером, а не авторитетом статьи из интернета.
- Строить схему эксперимента: baseline, одинаковые условия, p50/p95, воспроизводимость.
- Считать метрики качества данных и переводить их в трудозатраты и деньги.
- Оформлять ТЗ и листинги по ГОСТ 34.602 и ГОСТ 19, не теряя инженерный смысл.
Частые вопросы студентов
Хватит ли ER-диаграммы или нужен UML?
Для ВКР по Data Engineering ER-модель обязательна как уровень хранения, UML class — как уровень домена. Не смешивайте их в одном рисунке. Если вуз требует оформления по ГОСТ 34/19, добавьте отдельный лист «Схема данных» с явной легендой обозначений; C4-диаграмму контейнеров обычно принимают как дополнительную, но не заменяющую.
Где взять данные, если нет доступа к реальной системе?
Три законных варианта: открытые наборы, синтетика на генераторе (Faker или собственный скрипт) и обезличенная выгрузка по договору. Синтетику обязательно положите в приложение вместе с seed — тогда результаты воспроизводимы, и комиссия не спросит «а откуда цифры».
Нужно ли поднимать Kafka и Schema Registry?
Нет. Тот же механизм проверки контрактов воспроизводится на PostgreSQL и файловом реестре схем. Доказывать надо не наличие инфраструктуры, а корректность правил совместимости и измеримость выигрыша. Тяжёлый стек без экспериментальной части выглядит как декорация.
Как сформулировать практическую значимость?
Одно предложение с субъектом и цифрой: «снижение трудозатрат на подключение источника с X до Y часов за счёт канонической модели и валидации контрактов на входе». Если цифра не подтверждена — не пишите её, лучше честный диапазон и описание метода замера.
- Каждая задача из введения имеет отражение в главе и в выводах — сверьте построчно.
- Схема канона, ER-модель и примеры JSON/Avro описывают одни и те же сущности и поля.
- Есть baseline: замеры «до» получены на тех же данных и том же окружении.
- Метрики определены формулой, а не словами; единицы измерения указаны.
- Листинги оформлены по ГОСТ 19, ссылки на рисунки и таблицы расставлены в тексте.
- В приложении лежат генератор данных, seed и конфиги — эксперимент воспроизводим.
- Список источников: статья-первоисточник, спецификации JSON Schema/Avro, ISO/IEC 25010, ГОСТ 34.602.
- Нотация ради нотации. Десять диаграмм и ни одного правила именования и версионирования. Первый же вопрос «что будет, если добавится поле» ставит в тупик. Лечится контрактом данных и явным правилом эволюции схемы.
- Расхождение уровней. На ER одно, в JSON другое, в коде третье — точная копия ситуации, когда запись числа не соответствует вычислению, о которой идёт речь в статье. Сверяйте модели между главами построчно.
- «Стало быстрее» без базы сравнения. Замер только после оптимизации и без указания числа прогонов — не результат, а мнение. Нужны baseline, p50/p95 и одинаковые условия.
Источник: Римские цифры, узелки инков и буква x в магазине: как запись чисел определила всю историю математики (опубликовано 2026-03-28)