Материализации: view, table, ephemeral

Одна и та же модель может стать представлением, таблицей или вообще раствориться в SQL — это выбор материализации.

Материализация — стратегия, по которой dbt физически воплощает модель в хранилище: как представление (view), как таблицу (table) или как встраиваемый подзапрос (ephemeral).

Зачем выбор

Модель — это SELECT, но воплотить его можно по-разному, и выбор влияет на скорость запросов и стоимость хранения. dbt даёт три базовые стратегии плюс инкрементальную (следующий урок).

view — представление

По умолчанию модель становится view: в хранилище хранится только сам запрос, а данные считаются заново при каждом обращении. Плюс — мгновенное «обновление» (всегда свежо) и ноль места под данные. Минус — медленно, если запрос тяжёлый и к нему часто обращаются.

table — таблица

Материализация table при каждом dbt run физически пересчитывает результат и сохраняет как таблицу. Плюс — быстрые последующие чтения (данные уже посчитаны). Минус — занимает место и устаревает между запусками dbt.

-- models/marts/daily_revenue.sql
{{ config(materialized='table') }}

select order_date, sum(amount) as revenue
from {{ ref('orders') }}
group by order_date

ephemeral — без объекта в хранилище

Материализация ephemeral вообще не создаёт объект. Вместо этого dbt подставляет тело модели как CTE прямо в те модели, которые на неё ссылаются. Плюс — не засоряет хранилище промежуточными объектами. Минус — на неё нельзя сослаться в BI, и её не видно как отдельный объект.

Когда что выбирать

МатериализацияХранит данныеКогда выбрать
viewНет (только запрос)Лёгкие модели, staging, всегда нужна свежесть
tableДаТяжёлые витрины, к которым часто обращаются (BI)
ephemeralНет (CTE-вставка)Промежуточная логика, переиспользуемая внутри других моделей
incrementalДа, дописываетОчень большие таблицы (следующий урок)

Как работает под капотом

Материализация — это шаблон, по которому dbt генерирует DDL. Для view это create view ... as (select ...); для tablecreate table ... as (select ...) с предварительным дропом старой; для ephemeral dbt не шлёт DDL вовсе, а вшивает запрос как with __dbt__cte__model as (...) в потребителя. Задают материализацию через {{ config(materialized='...') }} в самой модели или скопом по папке в dbt_project.yml.

Частые ошибки

  • Делать table из всего подряд. Лёгкие staging-модели дешевле держать как view.
  • Делать view из тяжёлой витрины для BI. Каждый дашборд будет пересчитывать запрос — лучше table.
  • Ожидать, что на ephemeral можно сослаться извне. Её нет в хранилище как объекта.

Итоги

  • view хранит только запрос (свежо, но медленно), table хранит данные (быстро, но место и устаревание).
  • ephemeral встраивается как CTE и не создаёт объект — для промежуточной логики.
  • Материализацию задают через config(materialized=...) в модели или по папке в dbt_project.yml.
Проверьте себя
1. Чем материализация table отличается от view?
AНичем
Btable физически сохраняет посчитанные данные, view хранит только сам запрос
Cview быстрее table
Dtable нельзя использовать в BI
2. Что делает ephemeral-материализация?
AСоздаёт временную базу данных
BНе создаёт объект, а встраивается как CTE в модели, которые на неё ссылаются
CУдаляет данные после запуска
DШифрует таблицу
3. Какую материализацию разумно выбрать для тяжёлой витрины, к которой часто обращается BI?
Aview
Bephemeral
Ctable
Dникакую