Отслеживание изменений данных в dbt
Отслеживание изменений данных (Change data capture, CDC) позволяет выявлять новые, изменённые и удалённые строки в исходных данных, чтобы обрабатывать изменения без перестроения всей таблицы.
В этом руководстве объясняется, как использовать инкрементальные модели и снимки в dbt, чтобы поддерживать таблицы в актуальном состоянии, сохранять историю изменений или решать обе задачи. Чтобы выбрать оптимальный подход для своего проекта, обратитесь к разделу Выбор инкрементальных моделей или снимков. Информацию о частоте запуска заданий, потоках и динамических таблицах см. в разделе Данные в dbt в режиме, близком к реальному времени, в том числе в подразделе CDC с помощью Snowflake Streams.
Как работать с CDC в dbt
Когда исходные данные меняются, вам может потребоваться обновить таблицу, сохранить старые версии или сделать и то и другое.
В dbt для этого обычно используется один из двух способов построения таблицы:
- Инкрементальная модель поддерживает таблицу в актуальном состоянии. При каждом запуске dbt обрабатывает новые или изменённые строки и заменяет старую строку с соответствующим значением
unique_key. - Снимок сохраняет историю. При каждом запуске dbt сравнивает исходные данные с последним снимком и добавляет строку при изменении записи, указывая
dbt_valid_fromиdbt_valid_to.
Снимки фиксируют изменения только при запуске, поэтому их следует запускать по расписанию, иначе вы можете пропустить изменения. Обратитесь к ответу на частый вопрос Как часто следует запускать команду snapshot?, где рекомендуется запускать её с периодичностью от одного раза в час до одного раза в день.
Выберите подход: последняя версия строки, история или и то и другое
Выбор подхода зависит от того, как источник предоставляет изменения и что вам нужно сохранять.
| Что вам нужно | Как источник хранит изменения | Что использовать |
|---|---|---|
| Только последняя версия строки | Добавляет строку для каждого изменения или перезаписывает строки, но содержит надёжную метку времени изменения | Инкрементальная модель |
| Текущая строка и старые версии | Перезаписывает строки и достаточно мал, чтобы сканировать его при каждом запуске | Снимок |
| Текущая строка и старые версии без полного сканирования источника при каждом запуске | Перезаписывает строки или добавляет строку для каждого изменения (после очистки данных) | Инкрементальная модель промежуточного слоя (staging), затем снимок, затем зависимая модель, сохраняющая только последнюю версию строки из снимка |
Примеры каждого подхода см. в разделе Выбор инкрементальных моделей или снимков.
Основные рекомендации
- Используйте инкрементальные модели, если вам нужны только текущие строки и вы можете выявлять новые или изменённые строки. Инкрементальная модель заменяет старую строку, поэтому объём обработки при каждом запуске остаётся небольшим, а версии, к которым вы никогда не будете обращаться в запросах, не хранятся.
- Используйте снимки, если вам нужно знать, как выглядела запись в определённый момент в прошлом. Снимок добавляет строку при изменении записи, благодаря чему сохраняется старая версия. Инкрементальная модель перезаписала бы её.
- Используйте оба подхода, если промежуточный слой должен оставаться актуальным при небольших затратах на обработку, а снимок должен хранить версии. Инкрементальная модель ограничивает объём обрабатываемых данных. Снимок сохраняет историю. Создавайте снимки моделей промежуточного слоя (или источников), а не итоговой таблицы, к которой обращаются пользователи: так вы будете отслеживать изменения источника, а не отчёта, который может меняться по другим причинам.
- Отдавайте предпочтение стратегии снимков
timestamp, если полеupdated_atнадёжно и его значение только увеличивается. Это позволяет dbt выявлять изменения по метке времени, а не сравнивать каждый столбец. Используйтеcheck, если метка времени отсутствует или ненадёжна, чтобы изменения строки всё равно фиксировались. - Если хранилище уже записывает список изменений (потоки), используйте инкрементальную модель. Хранилище уже выявило изменение, поэтому для его обнаружения снимок не нужен. Соответствующий пример см. в разделе CDC с помощью Snowflake Streams.