Перейти к основному содержимому

Выбор между инкрементальными моделями и снимками

Используйте инкрементальные модели, снимки или их сочетание в зависимости от того, нужны ли вам текущие значения, исторические версии или и то и другое.

Сравнение инкрементальных моделей и снимков​

Начните с этой таблицы, если уже знаете, какие данные нужно сохранять. Она поможет выбрать для вашего источника инкрементальную модель, снимок или их сочетание.

ПодходКогда использоватьКогда не использовать
Только инкрементальные моделиВам нужна последняя строка для каждого id, а источник уже содержит перечень изменений или надёжную временную метку измененияНа основе этой таблицы нужно отвечать на вопрос «как выглядела эта строка в прошлом месяце?»
Только снимкиИсточник перезаписывает строки, вам нужна история, и сканирование источника при каждом запуске допустимоИсточник только добавляет строки и никогда их не обновляет, либо таблица настолько велика, что полный запуск снимка обходится слишком дорого
Совместное использование инкрементальных моделей и снимковВам нужна инкрементальная подготовка данных, чтобы снизить стоимость запусков, и снимок для хранения историиВам нужна только одна из этих задач, либо вы собираетесь создавать снимок итоговой таблицы, к которой обращаются пользователи

Только инкрементальные модели​

Выберите этот подход, если нужны только текущие значения каждой строки. Источник должен позволять определять новые или обновлённые строки одним из следующих способов:

  • Инструмент загрузки или поток, который записывает операции вставки, обновления и удаления (пример см. в разделе CDC с использованием Snowflake Streams)
  • Таблица, в которую только добавляются строки
  • Таблица, в которой строки перезаписываются и есть надёжная временная метка updated_at (или временная метка загрузки), по которой можно фильтровать данные

В этих примерах рассматриваются два клиента: Alice и Bob. После первого запуска у обоих статус trial:

idnamestatusupdated_at
1Alicetrial2026-01-01 00:00:00
2Bobtrial2026-01-01 00:00:00

На следующий день Alice становится клиентом со статусом active. При использовании стратегии merge и id в качестве unique_key следующий запуск обновит её существующую строку:

idnamestatusupdated_at
1Aliceactive2026-01-02 00:00:00
2Bobtrial2026-01-01 00:00:00

Текущий статус Alice — active. Её предыдущий статус trial больше не хранится в этой таблице.

Чтобы настроить такое поведение:

  • Используйте is_incremental(), чтобы при последующих запусках применять фильтр для новых или обновлённых строк
  • Укажите идентификатор клиента в параметре unique_key, чтобы dbt мог сопоставлять входящие строки с существующими
  • Выберите стратегию, например merge, которая обновляет совпадающие строки и вставляет новые

Подробности см. в разделах Настройка инкрементальных моделей и Об инкрементальных стратегиях.

Только снимки​

Выберите этот подход, если источник перезаписывает строки и вам нужна история, чтобы отвечать на вопросы вроде «Когда Alice стала активным клиентом?».

В том же примере запустите создание снимка до и после изменения статуса Alice. При использовании стратегии timestamp снимок сохраняет обе версии:

idnamestatusupdated_atdbt_valid_fromdbt_valid_to
1Alicetrial2026-01-01 00:00:002026-01-01 00:00:002026-01-02 00:00:00
1Aliceactive2026-01-02 00:00:002026-01-02 00:00:00null
2Bobtrial2026-01-01 00:00:002026-01-01 00:00:00null

Столбцы dbt_valid_from и dbt_valid_to показывают, когда действовала каждая версия. По умолчанию для текущей версии значение dbt_valid_to равно null.

Чтобы настроить снимок, укажите идентификатор клиента в параметре unique_key и выберите способ обнаружения изменений:

  • Используйте timestamp (рекомендуется), если есть надёжный столбец updated_at, значение которого увеличивается при каждом изменении строки
  • Используйте check, если в таблице нет надёжного столбца updated_at. dbt отслеживает изменения, сравнивая указанные вами столбцы или все столбцы

Регулярно запускайте dbt snapshot или dbt build по расписанию. Снимки фиксируют значения, доступные на момент запуска, поэтому они не могут восстановить промежуточные изменения, перезаписанные между запусками. Выбирайте расписание с учётом частоты изменения данных и необходимой детализации их истории.

О настройке и расписании см. в разделах Добавление снимков в DAG и Как часто следует запускать команду snapshot?.

Совместное использование инкрементальных моделей и снимков​

Используйте инкрементальные модели вместе со снимками, если вам нужна инкрементальная staging-модель для подготовки входящих данных перед сохранением их истории.

Следующий пример продолжает историю Alice и Bob. В нём используется источник с именем raw и таблицей customers, которая хранит одну текущую строку для каждого клиента. Замените эти имена на источник, определённый в вашем проекте.

Источник содержит две временные метки:

  • updated_at: когда изменились данные клиента.
  • _loaded_at: когда инструмент загрузки записал эту версию в хранилище. В этом примере предполагается, что значение заполнено и увеличивается с каждым загруженным изменением.

1. Обработка входящих изменений​

Создайте инкрементальную staging-модель, которая использует _loaded_at для поиска недавно загруженных строк и id для обновления данных соответствующего клиента.

models/staging/stg_customers.sql
{{
config(
materialized='incremental',
unique_key='id',
incremental_strategy='merge'
)
}}

select
id,
name,
status,
updated_at,
_loaded_at
from {{ source('raw', 'customers') }}
{% if is_incremental() %}
where _loaded_at >= (
select coalesce(max(_loaded_at), '1970-01-01')
from {{ this }}
)
{% endif %}

При первом запуске считываются все строки. При последующих запусках считываются строки, у которых значение _loaded_at не меньше последнего сохранённого значения. Использование >= позволяет включить строки с такой же временной меткой.

2. Сохранение исторических версий​

Создайте снимок staging-модели. Он использует updated_at для обнаружения изменений в данных каждого клиента.

snapshots/customers_snapshot.yml
snapshots:
- name: customers_snapshot
relation: ref('stg_customers')
config:
strategy: timestamp
unique_key: id
updated_at: updated_at

Создавайте снимки источников или staging-моделей с минимальными преобразованиями. Оставляйте бизнес-логику в последующих моделях, чтобы изменения этой логики не становились частью истории источника.

3. Выбор текущих значений для отчётности​

Создайте модель, которая выбирает текущую версию каждого клиента:

models/marts/dim_customers_current.sql
select
id,
name,
status,
updated_at
from {{ ref('customers_snapshot') }}
where dbt_valid_to is null

Запускайте эти ресурсы в порядке зависимостей: staging-модель, снимок, затем модель для отчётности. Можно использовать dbt build, выбрав все три ресурса.

После того как запуск зафиксирует изменение данных Alice, staging-модель и модель для отчётности будут показывать её статус как active. Снимок сохранит обе версии — trial и active, как показано в предыдущих примерах.

Если источник уже содержит даты начала и окончания действия версий (или перечень изменений, который нужно сохранить целиком), снимок может не понадобиться. Загружайте эти изменения инкрементально с помощью append или merge и выбирайте последнюю строку с помощью SQL-фильтра.

Что ещё следует учитывать​

  • Физическое удаление: инструменты загрузки часто помечают строку как удалённую. Снимки могут закрывать старую версию строки или добавлять запись об удалении с помощью hard_deletes. В инкрементальных моделях удаление необходимо обрабатывать в операции merge (или отдельной инструкцией delete).
  • Изменения, поступающие с задержкой: расширьте инкрементальный фильтр, чтобы захватывать данные за период немного раньше последнего запуска, и определите, в каких случаях безопаснее использовать --full-refresh. См. раздел Настройка инкрементальных моделей.
  • Несколько изменений за один запуск: в инкрементальных моделях перед выполнением merge оставляйте только последнее изменение для каждого id.
  • Изменение столбцов источника: используйте on_schema_change, чтобы управлять обработкой изменений схемы в инкрементальных моделях. Снимки могут добавлять новые столбцы, но при использовании стратегии check может потребоваться обновить check_cols.
  • Тесты: проверяйте, что unique_key в источнике или staging-модели уникален и не содержит null. Для снимков также проверяйте уникальность сочетания (unique_key, dbt_valid_from), отсутствие пересечений интервалов dbt_valid_from / dbt_valid_to и наличие не более одной текущей версии для каждого идентификатора (dbt_valid_to равно null). Отслеживайте свежесть данных источника, чтобы выявлять задержки загрузки.
  • Стоимость: организуйте таблицу по временной метке изменения и используйте фильтры, чтобы ограничить объём данных, сканируемых при каждом запуске. См. раздел Об инкрементальных стратегиях.

Связанная документация​

Нашли ошибку?

0
Loading