第3章 データロード・アンロードと接続 / 想定学習時間:30〜40分 / 最終確認:2026年8月

3-5. Dynamic Tables(宣言的パイプラインとTARGET_LAG)

🎯 この節の学習目標

1. Dynamic Table とは:結果を宣言するテーブル

3-4 の Streams+Tasks では、「差分を捕捉する Stream を作り、MERGE を書き、タスクをスケジュールして RESUME する」という手続きを自分で組み立てました。Dynamic Table(ダイナミックテーブル)は、この発想を逆転させます。「欲しい結果(SELECT)」と「どれくらい新鮮であってほしいか(TARGET_LAG)」だけを宣言すれば、リフレッシュの段取りは Snowflake が自動で管理する——これが宣言的パイプラインです。

-- 「この SELECT の結果を、5分以内の鮮度で保ち続けてほしい」と宣言する
CREATE DYNAMIC TABLE sales_clean
  TARGET_LAG = '5 minutes'
  WAREHOUSE = etl_wh
  AS
  SELECT sale_id,
         CAST(amount AS NUMBER(10,2)) AS amount,
         sale_date
  FROM raw_sales
  WHERE amount IS NOT NULL;

作成後は、ソースの raw_sales が変化すると、Snowflake が TARGET_LAG を満たすように自動でリフレッシュします。Stream の作成も、MERGE 文も、タスクのスケジュール管理も不要です。

2. TARGET_LAG と DOWNSTREAM:鮮度の指定

Dynamic Table の鮮度はラグ(lag)=「ソースの変更が反映されるまでの遅れの目標値」で指定します。指定方法は2つあります。

指定意味使いどころ
TARGET_LAG = '5 minutes' など「ソースから最大でもこの時間以内の遅れに保つ」という鮮度目標。Snowflake がこれを満たすようにリフレッシュ間隔を調整するパイプラインの最終段(消費者に鮮度を約束するテーブル)
TARGET_LAG = DOWNSTREAM自分では具体的な時間を持たず、下流の Dynamic Table のラグ要求に合わせて必要なときだけリフレッシュするパイプラインの中間段。下流が必要とする頻度でだけ動くため無駄がない
ソーステーブルraw_sales(通常のテーブル。変更が随時発生)
自動リフレッシュ(可能なら増分)
中間 Dynamic Tablesales_clean:TARGET_LAG = DOWNSTREAM(下流の要求に合わせて動く)
自動リフレッシュ(依存関係も Snowflake が把握)
最終 Dynamic Tablesales_daily:TARGET_LAG = '5 minutes'(消費者への鮮度目標)
BI・分析での利用常に「5分以内の鮮度」で参照できる

図:Dynamic Table を連ねた宣言的パイプライン。中間段は DOWNSTREAM、最終段に具体的な TARGET_LAG を置くのが定石

📝 試験のポイント

TARGET_LAG は「必ずこの間隔でリフレッシュする」というスケジュールではなく、鮮度の目標値です。また、パイプラインを連ねる場合に中間テーブルへ DOWNSTREAM を指定すると、下流の必要に応じてだけリフレッシュされるという趣旨の出題がされやすいので、2つの指定の役割分担を押さえましょう。

3. 自動リフレッシュ:増分とフル

Dynamic Table のリフレッシュは Snowflake が自動で実行します。このとき、クエリの内容に応じて2つの方式が使い分けられます。

どちらを使うかはクエリの内容から Snowflake が自動判定します。ユーザーが MERGE 文や差分ロジックを書く必要はありませんが、「増分で処理できるクエリの方がコスト効率が良い」という感覚は持っておきましょう。なお、Dynamic Table の定義クエリには一部使えない構文があります(たとえば外部関数など)。細かい一覧を暗記する必要はありませんが、「どんな SELECT でも増分化できるわけではなく、制約もある」という点は覚えておいてください。

4. Streams+Tasks との比較

同じ「継続的な変換パイプライン」を作るにも、Streams+Tasks(手続き的)と Dynamic Tables(宣言的)では発想が異なります。

Streams + Tasks(手続き的)Dynamic Tables(宣言的)
何を書くかStream の作成、MERGE などの変換ロジック、タスクのスケジュールと依存関係(AFTER)を自分で書く結果の SELECT と TARGET_LAG だけを書く
リフレッシュ制御SCHEDULE / WHEN 句で自分で制御するSnowflake が鮮度目標から自動で調整する
差分処理Stream のメタデータ列を使って自分で実装可能なら自動で増分リフレッシュ
向いている場面ストアドプロシージャ呼び出しや通知などSQL 変換以外の処理を挟みたい、実行タイミングを厳密に制御したいSQL で表現できる変換の連鎖を、シンプルに・少ないコードで保ちたい

💡 具体例:同じ要件を2通りで考える

「raw_sales の変更を5分以内に集計テーブルへ反映したい」という要件を考えます。Streams+Tasks なら、CREATE STREAM → MERGE 文の作成 → SCHEDULE = '5 MINUTE'WHEN SYSTEM$STREAM_HAS_DATA(...) のタスク作成 → ALTER TASK ... RESUME、という4段階の構築が必要です。Dynamic Tables なら CREATE DYNAMIC TABLE ... TARGET_LAG = '5 minutes' AS SELECT ...1文で完結します。変換が SQL で書き切れるなら Dynamic Tables の方がはるかにシンプルです。

5. モニタリング

Dynamic Table のリフレッシュ状況は、次の方法で確認できます。

-- リフレッシュ履歴の確認
SELECT name, refresh_start_time, refresh_action, state
FROM TABLE(INFORMATION_SCHEMA.DYNAMIC_TABLE_REFRESH_HISTORY())
WHERE name = 'SALES_CLEAN'
ORDER BY refresh_start_time DESC;

✅ この節のまとめ

練習問題

問1. Dynamic Table の TARGET_LAG = '5 minutes' の意味として最も適切なものはどれか。

  1. 正確に5分ごとにフルリフレッシュを実行するスケジュール設定である
  2. ソースデータからの遅れを最大でも5分程度に保つ、という鮮度の目標値である
  3. クエリの実行時間を5分以内に制限するタイムアウト設定である
  4. Time Travel の保持期間を5分に設定するオプションである
解答と解説を見る

正解:B

TARGET_LAG は「ソースの変更が反映されるまでの遅れをこの範囲に保ちたい」という鮮度目標で、Snowflake がそれを満たすようにリフレッシュのタイミングを自動調整します。Aのような固定スケジュールではなく、変更がなければリフレッシュを省くこともできます。Cのタイムアウトや、Dの Time Travel 保持期間とは無関係です。

問2. Dynamic Table を連鎖させたパイプラインで、中間段のテーブルに TARGET_LAG = DOWNSTREAM を指定した場合の動作はどれか。

  1. 下流のテーブルより常に先に、1分間隔でリフレッシュされる
  2. 下流の Dynamic Table のラグ要求に合わせて、必要なときだけリフレッシュされる
  3. リフレッシュが完全に停止し、手動リフレッシュのみ可能になる
  4. 下流のテーブルが通常のテーブルに変換される
解答と解説を見る

正解:B

DOWNSTREAM を指定した Dynamic Table は自分自身の時間目標を持たず、下流の Dynamic Table が鮮度を満たすために必要なタイミングでだけリフレッシュされます。中間段の無駄なリフレッシュを避けられる仕組みです。Aのような固定間隔ではありません。Cのようにリフレッシュが止まるわけでも、Dのようにオブジェクトの種類が変わるわけでもありません。

問3. Dynamic Table のリフレッシュに関する説明として正しいものはどれか。

  1. ユーザーが Stream と MERGE 文を書いて差分反映のロジックを実装する必要がある
  2. 常に結果全体を再計算するフルリフレッシュだけが実行される
  3. 可能な場合は増分リフレッシュが選ばれ、増分にできないクエリではフルリフレッシュになる
  4. リフレッシュのたびに ALTER TASK ... RESUME を実行する必要がある
解答と解説を見る

正解:C

Dynamic Table のリフレッシュ方式は Snowflake がクエリ内容から自動判定し、可能なら効率的な増分リフレッシュ、難しければフルリフレッシュになります。Aの差分ロジックの実装が不要である点こそが宣言的パイプラインの利点です。Bは誤りで、増分リフレッシュも存在します。Dのタスク操作は Streams+Tasks 方式の話で、Dynamic Table には不要です。

問4. Streams+Tasks ではなく Dynamic Tables を選ぶ理由として適切なものはどれか(2つ選べ)。

  1. 変換がSQLのSELECTで表現でき、記述するコードを最小限にしたい
  2. リフレッシュの段取り(差分処理・依存関係の実行順)を Snowflake に任せたい
  3. 変換の途中でストアドプロシージャの呼び出しや外部への通知を挟みたい
  4. タスクの実行タイミングを CRON 式で厳密に制御したい
解答と解説を見る

正解:A・B

Dynamic Tables は「結果の SELECT と鮮度目標だけを書けば、差分処理や依存関係の管理を Snowflake が自動化する」仕組みなので、AとBがそのまま利点です。CとDは逆に手続き的な制御が必要な場面であり、ストアドプロシージャの呼び出しや厳密なスケジュール制御をしたい場合は Streams+Tasks の方が適しています。