dbtにおけるviewマテリアライゼーションは、ストレージを消費せずに論理変換レイヤを素早く提供できる選択肢です。毎回のクエリ時に再計算されるため、軽量な整形・正規化・列名変更・型変換に適します。
本稿は、dbtの公式ドキュメントに基づく安定した挙動を前提に、試験で問われやすい知識と現場運用の要点を整理します。Snowflake/BigQuery/Redshift/Databricksなど主要DWHでの一般的な注意点もあわせて解説します。
dbtモデルをmaterialized: viewにすると、アダプタ固有の方言でCREATE VIEW(多くの環境ではCREATE OR REPLACE VIEW)として定義されます。データは保存されず、参照時に都度クエリが実行されます。モデルのデフォルトはviewである点も試験で頻出です。
dbtは依存関係をref/sourceで解決し、ビルド順序を制御します。viewは再作成時に定義が置き換わるため、コード変更の反映が早い一方、下流の依存クエリコストは元テーブルのスキャン量に依存します。権限やコメントの保持可否はアダプタ依存のため、grants/persist_docsを使って明示的に付与・反映する運用が安全です。
最小構成のviewモデル(models/stg_orders.sql)
{{ config(
materialized='view',
alias='stg_orders',
schema='staging'
) }}
select
cast(id as string) as order_id,
cast(customer_id as int) as customer_id,
order_date,
status
from {{ source('raw', 'orders') }}viewはビルド時にストレージを増やさない一方、参照するたびに基盤側で再計算されます。Snowflakeならコンピュートクレジット、BigQueryならスキャンバイト、Databricksならクラスタ時間が主なコスト源です。軽量変換であれば、変換をviewに任せて下流テーブルでのみ永続化する分離がコスト最適になりやすいです。
重い結合や大規模集計が頻繁に発生する場合は、tableやincrementalでの永続化を検討します。ephemeralは上流にインライン展開されるためDBオブジェクトは作られず、デバッグや権限付与の観点ではviewのほうが扱いやすいことがあります。
| マテリアライゼーション | 実体 | 更新タイミング | ストレージ |
|---|---|---|---|
| view | データ未保存(ビュー定義) | 参照時に再計算 | ほぼ0 |
| table | テーブルに保存 | dbt実行時に全再計算 | 中〜大 |
| incremental | テーブルに差分追加 | 差分計算時のみ | 中〜大(差分蓄積) |
| ephemeral | DBオブジェクトなし(CTE展開) | コンパイル時に上流へインライン | 0 |
dbt_project.ymlで階層ごとにデフォルトを切り替える例
models:
staging:
+materialized: view
+tags: [staging]
marts:
+materialized: table
+tags: [marts]
ソース直後のstaging層をviewで統一し、列名の正規化・型変換・単純フィルタで下流のモデルを安定化させます。重い結合やウィンドウ集計はmarts層でtable/incrementalに任せると、クエリコストの集中を避けられます。
権限周りでは、dbtのgrants設定で参照ロールを自動付与します。Snowflakeではアダプタ固有設定でSECURE VIEWが選べます。BigQueryのAuthorized ViewやDatabricksのUnity Catalog権限は、ビュー作成後の権限付与運用と組み合わせるのが一般的です。
軽量変換レイヤとしてのview配置
staging層の軽量整形ビュー(models/stg_customers.sql)
{{ config(materialized='view', alias='stg_customers') }}
select
cast(c.customer_id as int) as customer_id,
trim(lower(c.email)) as email_normalized,
coalesce(nullif(c.country, ''), 'UNKNOWN') as country,
c.created_at
from {{ source('raw', 'customers') }} c
where c.is_deleted = falseビューは毎回再計算されるため、重い結合・大規模集計・高頻度アクセスではコストや待ち時間が蓄積します。こうしたケースはtableやincrementalに切り替え、必要ならクラスタリングやソートキー、Z-ORDER(環境により異なる)などテーブル側の最適化を検討します。
dbtのviewは各DWHの“マテリアライズド・ビュー”とは別物です。dbtのmaterialized: viewは通常のビュー定義であり、ストレージに結果を保持しません。マテリアライズド・ビュー機能を使う場合は、アダプタや運用ポリシーに沿った別途の実装/管理が必要です。
重い処理はtable/incrementalへ切替(models/agg_sales.sql)
{{ config(
materialized='incremental',
unique_key='order_id',
incremental_strategy='insert_overwrite'
) }}
with base as (
select * from {{ ref('stg_orders') }}
)
select
order_id,
date_trunc('day', order_date) as order_day,
count(*) as order_cnt
from base
{% if is_incremental() %}
where order_date >= dateadd('day', -7, current_date)
{% endif %}
group by 1,2多くのアダプタでビューはCREATE OR REPLACEとして再定義されます。列追加や式変更は即時に反映されますが、下流が特定列に依存していると破壊的変更で失敗します。破壊的変更はキュレーション、タグ付け、prチェックとdbt testで早期検知しましょう。
権限やコメントの保持は挙動が環境依存です。dbtのgrantsとpersist_docs(アダプタ対応状況に依存)を設定し、ビルド後に確実に適用する運用が安全です。SnowflakeのSECURE VIEWなど、アダプタ固有オプションは該当環境のドキュメントに従ってください。
ビューでの権限とドキュメント反映(dbt_project.yml 抜粋)
models:
staging:
+materialized: view
+grants:
select: ['ANALYST_ROLE']
+persist_docs:
relation: true
columns: true
押さえる: 1) dbtモデルのデフォルトはview、2) viewは都度再計算で軽量変換に適する、3) 重い処理や高頻度参照はtable/incremental、4) ephemeralはDBオブジェクトを作らない、5) grants/persist_docsはアダプタ対応に依存、6) dbtのviewはDWHのマテリアライズド・ビューとは別。
演習: stagingをview、martsをtableに分離し、dbt testでstagingのスキーマを固定化。高コストな下流クエリがある場合は実行計画やスキャン量を見ながらmartsをincrementalへ切替える判断基準をメモ化しておくと現場と試験の両方で役立ちます。
CLI例(選択実行とテスト)
# stagingのviewだけビルド
$ dbt run -s tag:staging
# 下流のmartsのみ再ビルド
$ dbt run -s tag:marts
# 重要カラムのテストを実行
$ dbt test -m stg_orders stg_customersAnalytics Engineer
問題 1
頻繁に参照されるソーステーブルに対して、列名の正規化と軽いフィルタだけを行い、ストレージ増加を避けたい。下流では重い集計を別途テーブルとして永続化する計画。このときstagingモデルの最適なdbtマテリアライゼーションはどれか?
正解: A
軽量な変換でストレージを増やさず、定義変更の反映を即時にしたい場合はviewが最適。table/incrementalはストレージを消費し、ephemeralはDBオブジェクトを作らないため権限付与や独立参照が難しい。
viewは毎回再計算されるの?キャッシュは効く?
はい。ビュー自体は結果を保持しません。DWH側のクエリキャッシュや結果キャッシュが効く場合は再計算が短縮されることがありますが、保証や保持条件は各DWH実装に依存します。基本は再計算前提で設計します。
viewにインデックスやクラスタリングを設定できる?
一般にビューには直接設定できません。物理最適化は基となるテーブルや、テーブルとして永続化したモデルで行います。高頻度かつ重い処理はtable/incrementalへの切替を検討してください。
SnowflakeのSECURE VIEWやBigQueryのAuthorized Viewはdbtで扱える?
SnowflakeアダプタではconfigでSECURE VIEWの作成をサポートします(環境権限に依存)。BigQueryのAuthorized Viewはデータセット権限設定の運用が必要で、ビュー作成後に適切な権限を付与します。細部は各公式ドキュメントに従ってください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
dbt Model の基礎: SQL で定義する変換の最小単位
Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...
dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点
dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...
dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点
dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...
dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト
Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....
dbt_project.yml の読み方:主要設定と命名を最短で掴む
dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...