本稿は dbt Analytics Engineer 試験に備える受験者向けのドメイン別ミニ問題集です。範囲はモデリングとDAG、マテリアライゼーション、テスト、スナップショット、Jinja/マクロとパッケージ、実行とデプロイの6領域に分け、各領域で頻出の判断ポイントを短く確認できるようにしました。
問題設定は公式ドキュメントの挙動を前提にしており、バージョンに左右されにくい基本機能を中心に扱います。個別の UI 仕様やクラウド固有機能は細部が変わり得るため、コマンドや YAML 設定などのコア概念に注目してください。
dbt の DAG は、ref と source による依存関係定義から自動生成されます。ref は dbt 管理下のモデル間依存、source は外部テーブルの宣言とマッピングです。分析業務では、stg 層で命名規約に沿って正規化し、marts 層でビジネス粒度に集約するのが定石です。
試験では、DAG 一貫性、命名規約、依存の向き(上流→下流)、そして exposure による下流可視化の理解が問われがちです。ref を文字列連結で動的に作らない、source はソース定義の YAML と一致させる、などの基本を押さえます。
代表的な dbt DAG(sources→staging→marts)
ref と source の基本例
with src as (
select * from {{ source('raw', 'orders') }}
)
select
order_id,
cast(order_ts as timestamp) as order_ts,
customer_id
from srcマテリアライゼーションはパフォーマンスとコストのバランスを決定します。view は低コストで即時反映、table は安定した参照、incremental は大規模テーブルの更新負荷を抑制、ephemeral は一時サブクエリで最適化余地を残します。
試験では、データ量・更新頻度・再計算コストの組み合わせから適切な選択を判断させる設問が多いです。特に incremental の unique_key と on_schema_change の理解は得点源です。
| マテリアライゼーション | 永続性/ストレージ | 適合ユースケース | 更新コスト |
|---|---|---|---|
| view | 永続テーブルなし(メタデータのみ) | 小規模データ、即時反映が必要な探索 | 低(都度クエリ実行) |
| table | 物理テーブル | 安定配信、ダッシュボードの高速応答 | 中〜高(全再計算) |
| incremental | 物理テーブル(差分適用) | 大規模テーブルの部分更新 | 低〜中(差分のみ) |
| ephemeral | 非永続(サブクエリ展開) | 再利用される小さな中間計算 | N/A(上流に委譲) |
incremental モデルの基本パターン
{{ config(
materialized='incremental',
unique_key='order_id',
on_schema_change='append_new_columns'
) }}
with src as (
select * from {{ ref('stg_orders') }}
{% if is_incremental() %}
where updated_at > (select coalesce(max(updated_at), '1900-01-01') from {{ this }})
{% endif %}
)
select * from srcdbt のテストは generic(not_null, unique, relationships 等)と custom(SQL ベース)に大別されます。schema.yml に宣言した generic テストはメンテが容易で、失敗時にどの列・どのルールが崩れたかが即時に分かります。
source freshness は上流の遅延検知に有効です。error_after や warn_after を minutes/hours などで閾値設定し、dbt source freshness で評価します。
schema.yml での generic テストと source freshness
version: 2
sources:
- name: raw
tables:
- name: orders
freshness:
warn_after: {count: 60, period: minute}
error_after: {count: 120, period: minute}
models:
- name: stg_orders
columns:
- name: order_id
tests:
- not_null
- unique
- name: customer_id
tests:
- relationships:
to: ref('dim_customer')
field: customer_id
- name: status
tests:
- accepted_values:
values: ['placed','shipped','delivered','returned']スナップショットは履歴管理に用います。check strategy は特定列の値変化を検知、timestamp strategy は更新時刻列の前進で検知します。主キーはビジネスキー、updated_at は信頼できる時刻列を選定します。
試験では、dimension の遅延到着や再処理に関する設問が出ます。ソースが履歴を持たない場合は snapshot、持つ場合は単純な増分で十分か、の判断がポイントです。
顧客ディメンションの snapshot 例
{% snapshot customer_scd %}
{{ config(
target_schema='snapshots',
strategy='check',
unique_key='customer_id',
check_cols=['name','email','status']
) }}
select * from {{ source('raw','customers') }}
{% endsnapshot %}共通ロジックはマクロ化し再利用します。引数で挙動を変えることでモデルの重複を抑制できます。環境差異がある場合は adapter.dispatch によるアダプタ依存実装の切替も有効です。
パッケージは packages.yml に宣言します。セマンティックバージョニングの範囲指定(例: >=, <)で互換性を維持しつつアップデートを管理します。
単純なマクロと呼び出し、packages.yml
-- macros/safe_divide.sql
{% macro safe_divide(numerator, denominator, default=0) %}
case when {{ denominator }} = 0 or {{ denominator }} is null then {{ default }}
else {{ numerator }} / {{ denominator }} end
{% endmacro %}
-- models/fct_orders_rate.sql
select
date_trunc('day', order_ts) as day,
{{ safe_divide('sum(revenue)','nullif(count(*),0)', 0) }} as avg_rev_per_order
from {{ ref('stg_orders') }}
group by 1
# packages.yml
packages:
- package: dbt-labs/codegen
version: ">=0.12.0,<0.13.0"dbt build はモデル・シード・スナップショットの実行とテストを包括的に行います。単体実行は dbt run、検証のみは dbt test を使います。選択子(--select, --exclude)で対象を絞り、タグやパス、状態比較を活用します。
本番データセットを参照してステージングで下流を解決したい場合は --defer と --state を組み合わせます。state:modified+parents は差分開発で有効です。
selectors.yml と CLI 例
# selectors.yml
selectors:
- name: ci_changed
definition:
method: state
value: modified+parents
- name: marts_only
definition: tag:marts
# 直近変更と親をビルド(既存本番に defer)
# 事前に state を指す manifest.json を用意
# dbt build --selector ci_changed --defer --state path/to/artifacts
# タグ指定で実行
# dbt run --selector marts_onlyAnalytics Engineer
問題 1
大規模な orders テーブルは毎時間更新されます。新規行と更新行が混在し、order_id で一意に識別できます。ダッシュボードは 5 分以内の反映と安定した応答速度を求めています。最も適切なモデル定義はどれですか?
正解: A
要件は大規模データでの高頻度更新と安定応答。incremental で order_id を unique_key にし、updated_at 差分で取り込むのが最も現実的です。view はクエリ都度評価で遅く、table は毎回の全再計算が高コスト、ephemeral は永続化されずダッシュボード参照に不適です。
dbt build と dbt run のどちらを覚えるべきですか?
両方使えますが、試験ではユースケースの違いを理解しているかを見ます。build はモデル等の実行とテストを一括で行い、初回配信や CI に適します。run はモデルのみ実行で、局所的な再実行に向きます。
source freshness と generic テストはどのように使い分けますか?
source freshness は上流ソースの遅延検知、generic テストはモデルのデータ品質検証です。遅延は freshness、重複や null は generic(unique, not_null 等)で扱い、役割が補完関係になります。
増分モデルでスキーマが変わった場合の推奨対応は?
on_schema_change の設定を要件に合わせて選びます。新規列のみを許容するなら append_new_columns、厳密に揃えたいなら fail を選ぶなど、再フルリフレッシュの手順と併せて運用方針を定めます。
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)、設定優先度...