🔄

SIer出身エンジニアのためのdbt入門 ── ストアドプロシージャからdbtモデルへ

に公開

はじめに

SIerでストアドプロシージャやバッチ処理を書いていた人にとって、dbtは最もとっつきやすいモダンデータスタックのツールです。

なぜなら、dbtの本質は「SQLファイルをGit管理して、テストとドキュメントを自動生成する仕組み」だからです。SQLが書ければ、dbtは書けます。

この記事では、SIerで馴染みのある概念とdbtの概念を対応させながら、最短で理解するためのガイドを提供します。

ストアドプロシージャ vs dbtモデル

SIer時代の典型的な処理

-- ストアドプロシージャ: 売上集計バッチ
CREATE OR REPLACE PROCEDURE sp_aggregate_sales()
LANGUAGE SQL
AS
$$
BEGIN
    -- ステージングテーブルにINSERT
    TRUNCATE TABLE stg_sales;
    INSERT INTO stg_sales
    SELECT 
        order_id,
        customer_id,
        CAST(order_date AS DATE) as order_date,
        amount
    FROM raw_orders
    WHERE order_date >= CURRENT_DATE - 30;
    
    -- 集計テーブルにINSERT
    TRUNCATE TABLE mart_monthly_sales;
    INSERT INTO mart_monthly_sales
    SELECT 
        customer_id,
        DATE_TRUNC('month', order_date) as sales_month,
        COUNT(*) as order_count,
        SUM(amount) as total_amount
    FROM stg_sales
    GROUP BY customer_id, DATE_TRUNC('month', order_date);
END;
$$;

dbtで書くと

models/staging/stg_sales.sql:

SELECT 
    order_id,
    customer_id,
    CAST(order_date AS DATE) as order_date,
    amount
FROM {{ source('raw', 'orders') }}
WHERE order_date >= CURRENT_DATE - 30

models/marts/mart_monthly_sales.sql:

SELECT 
    customer_id,
    DATE_TRUNC('month', order_date) as sales_month,
    COUNT(*) as order_count,
    SUM(amount) as total_amount
FROM {{ ref('stg_sales') }}
GROUP BY customer_id, DATE_TRUNC('month', order_date)

違いは明白です。

  • CREATE PROCEDURETRUNCATE + INSERT が不要。SELECT文だけ書けばいい
  • {{ source() }} でソーステーブルを参照
  • {{ ref() }} でモデル間の依存関係を自動解決
  • 各モデルが独立したSQLファイルとしてGit管理される

JP1のジョブネット vs dbtのDAG

SIerでJP1のジョブネットを設計した経験がある人なら、dbtのDAG(有向非巡回グラフ)はすぐ理解できます。

JP1では「ジョブA → ジョブB → ジョブC」の実行順序をGUIで定義しますが、dbtでは{{ ref() }}を書くだけで依存関係が自動的に構築されます。

-- JP1のジョブネット(イメージ)
ジョブA: raw_orders → stg_orders
ジョブB: stg_orders → mart_daily_sales  (ジョブAの後に実行)
ジョブC: stg_orders → mart_customer_summary(ジョブAの後に実行)

-- dbtの場合
-- stg_orders.sql に {{ source('raw', 'orders') }} と書く
-- mart_daily_sales.sql に {{ ref('stg_orders') }} と書く
-- mart_customer_summary.sql に {{ ref('stg_orders') }} と書く
-- → dbt が自動的に実行順序を解決する

dbt run を実行するだけで、依存関係に基づいた正しい順序でモデルがビルドされます。

結合テスト vs dbt test

SIerではテスト仕様書をExcelで作成して手動でテストしていたものが、dbtではYAMLで定義して自動実行されます。

models/staging/schema.yml:

version: 2

models:
  - name: stg_sales
    description: "クレンジング済みの売上データ"
    columns:
      - name: order_id
        description: "注文ID(ユニーク)"
        tests:
          - unique
          - not_null
      - name: customer_id
        description: "顧客ID"
        tests:
          - not_null
          - relationships:
              to: ref('stg_customers')
              field: customer_id
      - name: amount
        description: "注文金額(正の値)"
        tests:
          - not_null
          - dbt_utils.accepted_range:
              min_value: 0

dbt test を実行すると、定義したテストが自動的に実行されます。

  • unique: ユニーク制約のチェック
  • not_null: NULL値がないことのチェック
  • relationships: 参照整合性のチェック(外部キー制約相当)
  • accepted_range: 値の範囲チェック

SIerで「NULLチェック」「一意性チェック」「参照整合性チェック」をSQLで手書きしていたものが、YAML数行で定義できます。

設計書 vs dbt docs

dbt docs generate を実行すると、モデル間の依存関係(リネージ)、テーブル定義、カラム説明がWebページとして自動生成されます。

Excel方眼紙で設計書を書く時代は終わりです。

最速で始める方法

  1. dbt Cloud の無料アカウントを作成
  2. Snowflakeの無料トライアルと接続
  3. 公式チュートリアル jaffle_shop を実施
  4. 自分のプロジェクトで小さなモデルを1つ作ってみる

SQLが書ける人なら、チュートリアルは2〜3時間で完了します。

まとめ

SIerの概念 dbtの概念
ストアドプロシージャ dbtモデル(.sqlファイル)
TRUNCATE + INSERT dbt run(自動でCTAS/マージ)
JP1ジョブネット DAG({{ ref() }}で自動構築)
テスト仕様書 + 手動テスト dbt test(YAMLで定義、自動実行)
Excel設計書 dbt docs(自動生成)
Git管理なし 全モデルがGit管理

SIerの経験がある人にとって、dbtは「今までやっていたことの効率化ツール」です。新しい概念を学ぶというより、既存の知識の延長で理解できます。


筆者はSIerから事業会社のデータエンジニアに転職し、Snowflakeベースのデータ基盤を運用しています。

👉 データキャリアLab
👉 dbt入門:SIer出身者が最速で理解するためのガイド

Discussion