Схеми даних та їх еволюція
1) Навіщо це iGaming-платформі
Надійність: зміни в даних не ламають звіти, API і моделі.
Швидкість фіч: безпечно додаємо поля (KYC/RG/PSP), не зупиняючи стріми.
Регуляторика: простежуваність і відтворюваність (audit/lineage, DSAR, Legal Hold).
Вартість: мінімізуємо «переливи» і даунтайм бекфілів.
2) Типи схем і де вони живуть
Події (стріми): `payments. deposit_accepted`, `game. round_finished`.
OLTP/DDL: нормалізовані таблиці (KYC, акаунти, ліміти).
DWH/вітрини (Gold): денормалізовані агрегати під BI/ML.
Feature Store: онлайнові/офлайнові фіч-сети з гарантіями узгодженості.
Контракти зовнішніх партнерів: PSP, провайдери ігор, маркетингові джерела.
Нотації: Avro/Protobuf (стріми), JSON Schema (інтеграції), SQL DDL (DWH), Parquet schema (lake).
3) Сумісність (ядро еволюції)
Backward-compatible: нові продьюсери → старі консьюмери (додали поле c default/nullable).
Forward-compatible: старі продьюсери → нові консьюмери (новий читач ігнорує зайве).
Full-compatible: і те, і інше (бажана мета для подій).
Breaking-changes: перейменування/видалення поля, зміна типу/семантики, зміна ключа/partitioning.
Правило 1: події еволюуємо через додавання, не через зміну.
Правило 2: видаляти - тільки в MAJOR версії схеми після періоду депрекейту.
4) Семантичні версії та політики
`MAJOR. MINOR. PATCH'для кожної схеми/вітрини/фіч-сету.
MAJOR - несумісний (новий topic/таблиця/фіч-сет, dual-run).
MINOR - сумісно (нові nullable/default поля, нові enum-значення).
PATCH - правки описів/лімітів/коментарів.
Життєвий цикл поля: experimental → active → deprecated → removed (з датами і власником).
5) Реєстр схем і контракти даних
Schema Registry: зберігає версії, сумісність, еволюцію і власників.
Data Contract: фіксує схему + SLO якості + приватність (див. розділ «Валідація даних»).
json
{
"type":"record","name":"deposit_accepted","namespace":"payments",
"fields":[
{"name":"event_id","type":"string"},
{"name":"occurred_at","type":{"type":"long","logicalType":"timestamp-micros"}},
{"name":"user_id","type":"string"},
{"name":"brand","type":"string"},
{"name":"country","type":"string"},
{"name":"psp","type":"string"},
{"name":"method","type":"string"},
{"name":"amount","type":{"type":"bytes","logicalType":"decimal","precision":18,"scale":2}},
{"name":"currency","type":{"type":"enum","name":"Currency","symbols":["EUR","USD","TRY","BRL"]}},
{"name":"risk_score","type":["null","int"],"default":null}, // MINOR+
{"name":"kyc_level","type":["null",{"type":"enum","name":"Kyc","symbols":["L0","L1","L2","L3"]}],"default":null}
],
"compatibility":"FULL","owner":"team-payments"
}
6) Патерни міграцій
6. 1 Події (стріми)
Additive-only: додаємо поля з default/nullable; старі консьюмери не ламаються.
Enum-розширення: нові символи вважаються MINOR, консьюмери зобов'язані мати гілку'else/unknown'.
MAJOR-міграція: новий topic'payments. deposit_accepted. v2', dual-write, shadow-reads, потім перемикання консьюмерів.
6. 2 DWH/вітрини
Blue-Green таблиці: `gold. revenue_v2' поруч з'v1'; матеріалізуємо, звіряємо, перемикаємо BI.
Backfill: реплей за снапшотами + idempotent merge (за ключами/версіями).
SCD: тип 2 для повільно мінливих атрибутів (ліміти, KYC, VIP-статуси).
6. 3 Feature Store
Dual-serve: старий фіч-сет обслуговується паралельно новому; модель обслуговується через роутер.
Point-in-time узгодженість: еволюція не повинна ламати PITA-джойни (timestamp/гранулярність незмінні при MINOR).
7) Таксономія змін (чек-лист)
Безпечні (MINOR):- додавання'nullable/default'поля;
- розширення enum (з'unknown'-гілкою у споживача);
- додавання неключового індексу/коментаря/описів.
- зміна масштабу/одиниць (наприклад, amount в центах → в основній валюті) - тільки в MAJOR;
- перенесення довідника/референса - через шар подання.
- перейменування/видалення поля;
- зміна типу/формату/ключа/partition;
- зміна семантики (наприклад,'bonus _ amount'з «нараховано» → «списано»).
8) Лінтери схем і тести сумісності
Schema-lint: стиль імен ('snake _ case'), обов'язкові мітки ('owner','doc','pii'), формат дат/валют.
Compat-tests: перевіряємо нову версію проти реєстру (backward/forward/full).
Consumer-contract-tests: кожен сервіс поставляє «приклад корисного навантаження» і очікування; проганяємо на CI при зміні схеми.
Golden-datasets: набір реальних і «злих» прикладів (нові enum, порожні/пізні поля, рубіжні значення сум).
9) Довідники, enum і локалізація
Reference-data (країни/валюти/PSP/провайдери): окремі версії та SLA оновлень; не вшивати в код подій.
Locale/часові пояси: зберігати UTC в подіях + явну локаль для презентації.
Правила юрисдикцій: вікові прапори, обмеження промо - у вигляді довідників з датами дії.
10) Мультибренд/мультиюрисдикції та PII
Тенант-ізоляція: 'brand','country','license'- обов'язкові поля з enum; роутинг по них.
PII-політика на рівні схеми: позначаємо поля'pii = true', застосовуємо маски/токенізацію; у подіях - тільки токени.
DSAR: наявність'source _ id/trace _ id'для видалення/пошуку; Legal Hold на MAJOR-міграціях.
11) Версіонування DDL і Lake
DDL-міграції: декларативні міграції (Liquibase/Flyway/dbt), зберігання в VCS, рев'ю власником домену.
Формати в Lake: Avro/Parquet - фіксуємо еволюцію полів; при MAJOR - нова таблиця/шлях'.../v2/'.
Partitioning: зміна партій (наприклад, «date'→'date,brand») - тільки через MAJOR і подвійний запис.
12) Приклади iGaming
12. 1 PSP розширив методи
Доданий'method = «MEFETE»'в enum.
MINOR реліз схеми'deposit _ accepted v1. 8. 0`; консьюмери, які не знають MEFETE, відправляють в'unknown _ method'гілку.
12. 2 Провайдер ігор додав поля
В'game. round_finished' додано'jackpot _ id'( nullable).
Вітрина'gold. game_rounds_v3' отримує MINOR; старі звіти працюють, нові вважають джекпоти.
12. 3 RG-атрибути
Перехід від булевого'self _ excluded'до статусового'rg _ state ∈ {none, limit, cooldown, self_excluded}' - MAJOR, новий topic + dual-write + міграція вітрин і моделей.
13) Процес еволюції (від ідеї до перемикання)
1. Proposal (ADR): навіщо змінюємо, тип сумісності, оцінка ризику і порушених споживачів.
2. Дизайн і контракт: схема до реєстру, semver, політика сумісності.
3. Тести: linters, compat, consumer-contracts, реплей на golden-сетах.
4. Розгортання: dual-write / blue-green / shadow-reads; алерти.
5. Звірка: бізнес-баланси/інваріанти (див. «Валідація даних»).
6. Switch: перемикаємо консьюмерів/BI/фічі.
7. Deprecate: freeze старої схеми, grace-period, видалення і архів.
14) Метрики і SLO еволюції
Success-rate міграцій, час dual-run, частка подій нового формату, обсяг backfill, lag/freshness.
Інциденти сумісності (P1/P2), якість вітрин після перемикання.
Cost: $/TB переливу, $/годину dual-write, завантаження кластера.
Compliance: 0 PII-витоків, SLA DSAR/Legal Hold дотримані.
15) Інструменти та артефакти
15. 1 Політика сумісності (реєстр)
yaml schema: payments. deposit_accepted compatibility: FULL default_nulls: true enums:
currency: {allow_new_symbols: true, require_consumer_unknown_branch: true}
pii: false owners: ["team-payments"]
reviewers: ["data-governance","security-dpo"]
15. 2 Паспорт міграції (шаблон)
yaml change_id: MIG-2025-041 scope: game. round_finished -> v3 type: MAJOR plan:
dual_write: true shadow_reads: consumers: ["gold-rounds","rg-models"]
backfill: {from: "2025-01-01", mode: "idempotent-merge"}
validation:
invariants: ["sum_bets = sum_wins + margin + bonuses"]
freshness_delta_p95_max: "PT5M"
switch_criteria:
error_rate_max: 0. 1%
kpi_diff_pp_max: 0. 5 deprecate_after: "2025-12-31"
15. 3 Лінтер імен і типів (правила)
'snake _ case', UTC timestamps, DECIMAL (18,2) для сум,'country'за ISO-3166-1 alpha-2,'currency'за ISO-4217.
Ніяких'free _ text'для enum-полів; довідники - зовнішні.
16) Дорожня карта впровадження
0-30 днів (MVP)
1. Включити Schema Registry + policy сумісності для ключових подій (payments, game_rounds, user).
2. Лінтери/compat-тести в CI; каталог власників і SLA відгуків.
3. Шаблони ADR і паспорт міграцій; чек-лист MAJOR.
30-90 днів
1. Blue-Green для Gold-вітрин; dual-write для критичних тем.
2. Consumer-contract-tests для основних сервісів; golden-datasets.
3. Автоматичні diff-звірки і алерти при перемиканнях; звіти вартості.
3-6 місяців
1. Єдиний процес deprecate/remove з grace-period; архівування та Legal Hold.
2. Гео/тенант-специфічні схеми і ключі шифрування; DP-варіанти для чутливих ринків.
3. Каталог семантики полів (data dictionary) і живі діаграми lineage.
17) RACI
Data Governance (A/R): стандарти, реєстр, рев'ю міграцій, де-публікація.
Domain Owners (R): сенс полів, довідники, бізнес-інваріанти.
Data Platform (R): інструменти реєстру, compat-тести, dual-run/бекфіли.
Security/DPO (A/R): PII-політики, geo/tenant, DSAR/Legal Hold.
SRE/Observability (C): альберти, SLO еволюцій, capacity.
Product/Finance (C): валідація KPI, вікна перемикання.
18) Анти-патерни
«Правимо поле на льоту» без версій і dual-run.
Перейменування замість додавання нового поля → масові поломки.
Жорсткі enum без гілки'unknown'→ падіння при нових значеннях.
Єдиний довідник «в коді» для всіх юрисдикцій.
Бекфілл без idempotent-merge і чек-балансів.
Логи з PII і без trace_id для пошуку/DSAR.
19) Пов'язані розділи
Валідація даних, Походження і шлях даних, DataOps-практики, API аналітики і метрик, Аудит і версійність, Безпека даних і шифрування, Контроль доступу, MLOps: експлуатація моделей.
Підсумок
Еволюція схем - це процес, а не разова міграція: реєстр, версії та сумісність; dual-run і blue-green замість «перемикачів опівночі»; тести сумісності та бізнес-інваріанти замість удачі. Так дані залишаються стабільними, моделі - передбачуваними, звіти - коректними, а регулятори - спокійними.