Как правильно подложить подклад на рассорку с сущностью

Узнай, как подложить подклад на рассорку с сущностью без магии и лишних слёз — простые шаги и лайфхаки!

Ни один современный Data Lakehouse не обходится без грамотно устроенного слоя рассорки (staging). Самый чувствительный этап, это «подложить подклад» на уже существующую сущность, не повредив сырые данные и не потеряв целостность схемы. В статье разберёмся, что такое подклад, зачем он нужен, какие бывают стратегии и как применить их на практике.

Содержание

  1. Что такое «подклад» и «рассорка»
  2. Что значит «с сущностью»
  3. Стратегии подкладывания подклада
  4. Пошаговый алгоритм для Apache Spark / dbt
  5. Распространённые ошибки и как их избежать

Что такое «подклад» и «рассорка»

Рассорка (staging) — это временная или полу-временная зона, куда попадают сырые данные из источников без трансформаций.
Подклад (overlay) — это тонкий «слой-пластырь» поверх существующей таблицы, содержащий лишь дифф или корректировки, которые нужно применить атомарно.

  • Подклад не перезаписывает всю таблицу, а «накладывается» поверх, позволяя оставить оригинальные партиции нетронутыми.
  • Классический пример: исправление ошибок в нескольких строках факта продаж за прошлый квартал, когда полный пересчёт стоит слишком дорого.

Что значит «с сущностью»

Под «сущностью» в контексте хранилища подразумевается:

  • SCD Type 2-таблица (исторически изменяемая)
  • Facts-таблица с датой действия
  • Master-data (справочник)

Во всех случаях у нас уже есть:

  1. business key (уникальный идентификатор сущности),
  2. поле версии (valid_from / valid_to),
  3. партиционирование (обычно по дате).

Стратегии подкладывания подклада

Append-only patch

Самая простая стратегия: просто дописываем новые строки с тем же business key, но новым valid_from.
Плюсы: нет риска затереть старое.
Минусы: придётся потом чистить дубли.

Upsert (Merge) patch

Используем MERGE INTO (Delta Lake) или dbt snapshot.
Логика такая:

MERGE INTO staging.sales t
USING patch.sales_delta s
ON t.business_key = s.business_key
 AND t.valid_to = '9999-12-31'
WHEN MATCHED THEN UPDATE SET valid_to = s.valid_from
WHEN NOT MATCHED THEN INSERT (...)

Partition swap

Если ошибка затронула только одну партицию (например, 2023-11-15), можно:

  1. сформировать новую партицию с правильными данными,
  2. атомарно свапнуть партицию в метасторе.

Это самый быстрый способ при больших объёмах.

Пошаговый алгоритм для Apache Spark / dbt

Шаг 0. Подготовьте окружение

export DELTA_TABLE_PATH="s3://lakehouse/staging/sales"
export PATCH_PATH="s3://tmp/sales_patch_$(date +%F)"

Шаг 1. Создайте дельта-патч

spark.sql("""
 CREATE OR REPLACE TABLE delta.`$PATCH_PATH`
 AS SELECT * FROM source_view
 WHERE business_key IN (/список ключей с ошибками/)
""")

Шаг 2. Проверьте целостность

spark.sql("""
 SELECT business_key, COUNT(*) cnt
 FROM delta.`$PATCH_PATH`
 GROUP BY business_key

 HAVING cnt > 1
""").show

Шаг 3. Примените merge-патч

spark.sql("""
 MERGE INTO delta.`$DELTA_TABLE_PATH` t
 USING delta.`$PATCH_PATH` s
 ON t.business_key = s.business_key
 AND t.valid_to = '9999-12-31'
 WHEN MATCHED THEN UPDATE SET
 valid_to = current_timestamp
 WHEN NOT MATCHED THEN INSERT *
""")

Шаг 4. Проверьте и зафиксируйте метаданные

spark.sql("OPTIMIZE delta.`$DELTA_TABLE_PATH` ZORDER BY (business_key)")

Распространённые ошибки и как их избежать

  • Забыли отключить автоматическое кэширование → используйте spark.databricks.delta.optimizeWrite.enabled=false на время патча.
  • Нарушена последовательность версий → всегда проверяйте, что valid_from новой записи > max(valid_to) предыдущей.
  • Конфликт партиций → применяйте REPLACE WHERE вместо перезаписи всей партиции, если данные точечные.
  • Потеря метаданных → после ALTER TABLE DROP PARTITION сразу делайте MSCK REPAIR TABLE.
  1. Определите тип сущности и наличие историчности.
  2. Выберите стратегию: append, merge или partition swap.
  3. Сформируйте минимальный дифф-патч, проверьте дубликаты.
  4. Примените merge/upsert с правильной логикой valid_from/valid_to.
  5. Оптимизируйте таблицу и обновите статистику.
  6. Зафиксируйте версию в lakeFS / Delta log / Git LFS для возможности отката.

Следуя этим шагам, вы сможете «подложить подклад» на рассорку с сущностью быстро, безопасно и воспроизводимо. Удачных вам патчей и пусть ваши данные всегда будут актуальны!