GH GambleHub

Работа с историческими данными

1) Назначение и принципы

Цель: хранить и обрабатывать прошлые состояния так, чтобы отчеты, модели и расследования были воспроизводимыми, точными и комплаентными.

Принципы:
  • Time-aware by design: явные модели времени в схемах и запросах.
  • Reproducibility: один и тот же отчет за дату D всегда дает тот же результат.
  • Auditability: доказуемое происхождение (lineage), неизменяемые слои, WORM там, где нужно.
  • Cost-aware: архивные слои, компрессия, cold storage с понятными SLA.
  • Privacy-by-design: управление PII при ретроспективных операциях и правовых запросах.

2) Модели времени

Event-time: время фактического события (ставка, депозит).
Processing-time: когда система обработала запись (может отличаться).
Bitemporal: хранение и event-, и processing-времени для правок задним числом.
Validity-интервалы: `valid_from`, `valid_to`, `is_current`.
As-of queries: выборка данных «как знали в момент T».

Шаблон полей:
sql event_time TIMESTAMP, -- event time processed_at TIMESTAMP, -- TIMESTAMP valid_from processing time, -- start of version validity valid_to TIMESTAMP, -- end of validity (NULL if current)
is_current   BOOLEAN

3) Слои хранения и форматы

Lakehouse: Bronze (raw append-only) → Silver (clean/SCD/нормализация) → Gold (витрины).
ACID-форматы: Delta/Iceberg/Hudi (MERGE/Upsert, time-travel, snapshots).
Tiered storage: hot/warm/cold + WORM для регуляторных артефактов.
Партиционирование: `event_date`, `market`, `tenant`; кластеризация/Z-order по частым предикатам (user/game/provider).

4) Историзация измерений (SCD)

SCD I: перезапись — для некритичных правок.
SCD II: полная история; рекомендуется для RG/KYC/каналов трафика/атрибутов игр.
SCD III: «до/после» — редкие кейсы сравнения.

Пример SCD II:
sql
MERGE INTO dim. users_scd t
USING stage. users u
ON t. user_pseudo_id = u. user_pseudo_id AND t. is_current = TRUE
WHEN MATCHED AND (t. rg_status <> u. rg_status OR t. country <> u. country) THEN
UPDATE SET is_current = FALSE, valid_to = CURRENT_TIMESTAMP
WHEN NOT MATCHED THEN
INSERT (user_pseudo_id, country, rg_status, valid_from, valid_to, is_current)
VALUES (u. user_pseudo_id, u. country, u. rg_status, CURRENT_TIMESTAMP, NULL, TRUE);

5) История фактов: снимки и бitemporal

Снимки (snapshots): снимок агрегатов на конец дня/месяца (например, баланс кошелька) — ускоряют воссоздание исторических отчетов.
Bitemporal факты: фиксируем event-time и processing-time, чтобы отличать поздние исправления от ретроспективных расчетов.
Exactly-once история: дедуп по `event_id` + идемпотентные MERGE.

6) Time-travel и воспроизводимость

Time-travel: чтение таблиц «на момент Т» для отладки, инцидентов, сверок.
Версионирование логики: артефакты трансформаций (версии SQL/DBT, контейнеров) и метки «logic_version» в выходных таблицах.
Frozen outputs: Gold-артефакты отчетности фиксируются и не переписываются, доступен hash и журнал экспорта.

Пример as-of запроса:
sql
SELECT
FROM silver. fact_bets VERSION AS OF 1678901234567
WHERE event_date = DATE '2025-10-31';

7) Backfill и Reprocessing

Backfill: первичная/догрузка исторического диапазона.
Reprocessing: пересчет после исправления багов или смены бизнес-правил.

Гардерейлы:
  • Идемпотентность (MERGE/upsert), диапазоны, квоты, «темный прогон» (dry-run) с сравнением метрик.
  • Маркируем результат: `recalc_reason`, `logic_version`, `reprocessed_at`.
Runbook (схема):

1. Freeze текущие Gold; 2) проверка DLQ/DQ; 3) прогон Silver; 4) сравнение метрик; 5) пересборка Gold; 6) публикация и подпись.

8) Сверки точности (reconciliation)

Контрольные суммы: сверка оборотов/количеств с OLTP, PSP/провайдерами.
Двухконтурная проверка: независимый pipeline на выборке (A/B сравнение).
Допуски: например, расхождение GGR ≤ 0.2% за день.

SQL-образцы:
sql
-- Duplicates
SELECT transaction_id, COUNT() c
FROM silver. payments
GROUP BY transaction_id
HAVING COUNT() > 1;

-- Unknown Currencies/Markets
SELECT p. currency
FROM silver. payments p
LEFT JOIN ref. currencies r ON r. code = p. currency
WHERE r. code IS NULL;

9) Валюты, время, календарь: историческая корректность

FX на дату события: фиксируем `fx_rate_used` и `fx_source`.
Локальное время рынка: DST/таймзоны через справочник календарей.
Праздники/сезонность: отдельная таблица календаря, используем в моделях и отчетах.

Пример нормализации FX:
sql
SELECT p. transaction_id,
p. amount_orig,
r. rate AS fx_rate_used,
p. amount_orig r. rate AS amount_base,
r. fx_source
FROM bronze. payment_events p
JOIN dim. fx_rates r
ON r. date = DATE(p. event_time) AND r. ccy_from = p. currency AND r. ccy_to = 'EUR';

10) PII, комплаенс и Legal Hold

PII-минимизация: псевдонимизация, отдельный защищенный маппинг.
DSAR/RTBF: вычислимые проекции и селективные редактирования исторических слоев; исключения по законной обязанности хранения документируются.
Legal Hold: флаги «заморозки» удалений на диапазоны/объекты, WORM для отчетных артефактов.
Аудит: неизменяемые логи доступов и экспортов.

11) DQ и lineage для истории

DQ-как-код (пример):
yaml table: silver. fact_bets slo:
completeness_percent: 99. 5 freshness_minutes: 60 rules:
- name: unique_bet type: unique columns: [bet_id]
severity: critical
- name: market_known type: in_set column: market set_ref: ref. markets
- name: ts_in_range type: temporal expression: "event_time BETWEEN date_sub(now(), interval 5 year) AND now()"

Lineage: фиксируем версии входов/трансформаций/выходов; граф зависимостей обязателен для ретроизменений.

12) Производительность и стоимость

Партиционирование: по дате/рынку/тенанту; агрессивная кластеризация по `user_pseudo_id`/`game_id`, если часто фильтруем.
Форматы: Parquet + статистики/компрессия; регулярный VACUUM/OPTIMIZE.
Материализация: precompute для «дорогих» исторических агрегаций; снапшоты для поквартальной/годовой отчетности.
Архивирование: перевод старых партиций в cold storage (SLA на восстановление документируется).
Сэмплирование: только для исследовательских задач, не для регуляторки/финансов.

13) Исторические фичи для ML

Feature registry: каждая фича имеет формулу, owner, SLO, `model_version`.
Согласованность online/offline: одна кодовая база трансформаций, тесты репроходимости.
Дрейф признаков: PSI/KS по периодам, хранение исторических распределений.

14) Паттерны запросов

As-of (на дату): воспроизводимость отчетов.
Cohort-анализ: когорты регистраций/первых депозитов, rolling окна.
Slowly changing facts: корректные join’ы с SCD II (`event_time BETWEEN valid_from AND COALESCE(valid_to, '9999-12-31')`).

Пример join’а с SCD II:
sql
SELECT b. bet_id, u. rg_status
FROM silver. fact_bets b
JOIN dim. users_scd u
ON u. user_pseudo_id = b. user_pseudo_id
AND b. event_time >= u. valid_from
AND (u. valid_to IS NULL OR b. event_time < u. valid_to);

15) Процессы и RACI

R (Responsible): Data Engineering (модели/SCD/backfill), Data Platform (ACID/архив), Finance/Compliance (сверки/требования хранения).
A (Accountable): Head of Data/CDO.
C (Consulted): Legal/DPO (DSAR/RTBF/Legal Hold), SRE (стоимость/SLA), Архитектура.
I (Informed): BI/Продукт/Маркетинг/Операции.

16) Дорожная карта внедрения

MVP (3–5 недель):

1. ACID-таблицы с time-travel (Delta/Iceberg/Hudi) и базовое партиционирование.

2. SCD II для ключевых измерений (users/games/providers).

3. Ежедневные snapshots критичных агрегатов (GGR Daily).

4. DQ-как-код (uniqueness/in_set/temporal) + lineage-граф.

Фаза 2 (5–10 недель):
  • Bitemporal факты, as-of API/SQL-шаблоны, runbooks backfill/reprocessing.
  • FX/календарь/DST-обогащение, сверки OLTP↔DWH/провайдеры.
  • Архивирование cold storage, WORM для отчетных пакетов, Legal Hold.
Фаза 3 (10–16 недель):
  • Полная автоматизация «replay & what-if», сравнение метрик и алерты регрессий.
  • Исторические фичи и дрейф-контроль ML, chargeback по стоимости хранения.
  • Документация «as-of» метрик и воспроизводимых отчетов.

17) Чек-лист перед продом

  • Таблицы поддерживают time-travel; политики VACUUM/RETENTION согласованы.
  • SCD II реализован для критичных измерений; join’ы протестированы.
  • Снимки ключевых агрегатов на D/M доступны и проверены сверками.
  • DQ-правила активны; lineage отображает входы/выходы и версии логики.
  • DSAR/RTBF/Legal Hold протестированы на исторических слоях.
  • Архивирование и восстановление из cold storage документировано и проверено.
  • Стоимость хранения под контролем (cost/GB, доля cold, SLA восстановления).

18) Частые ошибки и как их избегать

Отсутствие явной модели времени: добавляйте event/processing/validity.
FX «задним числом»: всегда курс на момент события, хранить `fx_source`.
Неправильные join’ы с SCD: используйте интервал валидности, а не `is_current`.
Мутирующие Gold-витрины: отчетные выходы должны быть неизменяемыми (или с версионированием).
Без lineage/DQ: нет доказуемости и контрольных точек — вводите их с первого дня.
Неуправляемая стоимость: отключите горячие партиции, вакуумируйте, переводите в cold.

19) Глоссарий

As-of Query — запрос данных «как они выглядели на момент Т».
Bitemporal — одновременная фиксация event и processing времени.
Snapshot — материализованный снимок состояния/агрегатов на конец периода.
Time-travel — чтение исторических версий таблиц.
WORM — неизменяемое хранение (Write Once Read Many).

20) Итог

Работа с историческими данными — это не просто «длинное хранение», а дисциплина времени: явные модели event/processing/bitemporal, SCD и snapshots, reproducible as-of запросы, строгие сверки и комплаенс-контроли, наблюдаемость и экономная архитектура хранения. Следуя этому руководству, вы получите надежный исторический фундамент для отчетности, аналитики и ML, устойчивый к аудиту и изменениям бизнес-логики.

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Telegram
@Gamble_GC
Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

Нажимая кнопку, вы соглашаетесь на обработку данных.