LASSIC Media らしくメディア
dbtでデータ変換基盤を外注で構築
LASSIC IT事業部|元請(プライムベンダー)としてシステム保守・運用を受託
この記事のポイント
- dbtがELTのT(変換)をSQLとJinjaでどう管理するか、model・ref・sourceの関係を整理します。
- test・documentation・snapshotによる品質担保と、dbt Core/dbt Cloudの機能差を公式情報に基づき解説します。
- CI連携の仕組みと、導入・運用を外注する場合の委託範囲・発注準備を整理します。
目次
dbtとは何か — ELTの「T」を担う変換ツール
dbt(data build tool)とは、データウェアハウス(DWH)にロード済みの生データを、SQLのSELECT文で記述した変換ロジックによって分析用のデータモデルへと組み立てるツールを指します。dbt公式ドキュメントは、dbtが生データを信頼できるデータプロダクトへ変換するツールであり、データがウェアハウスの外に出ることなく変換を実行できる仕組みだと説明しています*1。
ELT(Extract・Load・Transform)という処理順序において、EL(抽出・ロード)を担うのはFivetranやCDC(変更データキャプチャ、データベースの変更を検知して連携する仕組み)ツールです。dbtはそのあとの「T(変換)」を担当する立ち位置であり、公式ドキュメントも変換モデルの実行を指して「ELTのT」と明記しています*1。データ取込やDWH構築そのものではなく、DWHに入った後のデータ整形・集計・品質担保を専門に扱う点が特徴です。
model・ref・sourceで組み立てる変換パイプライン
dbtにおける変換の最小単位は「model」です。model とは、`.sql`ファイルに書かれた1つのSELECT文であり、dbtがそのSELECT文をもとにDWH上にビュー・テーブルを作成します*1。1つのmodelが1つの変換ステップに対応し、複数のmodelを連結することで、生データから分析用テーブルまでの変換パイプラインを構築します。
modelどうしの依存関係は、`ref`というJinja関数(SQLにテンプレート機能を組み込む仕組み)で表現します。`{{ ref(‘モデル名’) }}`と書くと、そのモデルへの参照が解決され、dbtは`dbt run`実行時に依存順序を自動的に構築します*2。テーブル名を直接SQLに書き込む必要がないため、開発環境と本番環境でスキーマ名が異なっていても、コードを変更せずに動作します。
生データ側の入口にあたるのが「source」です。sourceは、EL(抽出・ロード)ツールが既にDWHに配置した生テーブルの名前・所在をYAMLで宣言する仕組みで、`{{ source(‘ソース名’, ‘テーブル名’) }}`の形でmodelから参照します*3。source定義を挟むことで、生データの由来を一元管理し、データ鮮度(freshness)の監視や、生データ段階でのテストも設定できます*3。
低頻度でしか更新されない小規模な参照データ(都道府県コード表、ステータスのマッピング表等)は、CSVファイルとして`seeds`ディレクトリに置き、`dbt seed`コマンドでDWHにテーブルとしてロードできます*1。これにより、Excelで管理しがちなマスタ値をバージョン管理下に置き、変換パイプラインの一部として扱えます。
test・documentation・snapshotによる品質担保
dbtとは、単なるSQL実行ツールではなく、変換結果の品質をコードとして検証できる点に価値があります。`dbt test`コマンドは、モデルの出力データに対するアサーション(成立すべき条件の宣言)を実行し、合否を判定します*4。テストにはGeneric test(`unique`・`not_null`・`accepted_values`・`relationships`という組み込み4種をYAML上でパラメータ化して繰り返し使う形式)と、Singular test(個別の検証ロジックをSQLファイルとして1本ずつ書く形式)の2種類があります*4。
ドキュメント機能も標準で備わっています。YAMLファイルにモデル・カラムの説明(description)を書き加えると、`dbt docs generate`でドキュメントサイトを生成でき、モデル間の依存関係を示すDAG(有向非巡回グラフ、処理の順序関係を矢印でつないだ図)が自動描画されます*5。仕様書を別途作成しなくても、コードとドキュメントが同じリポジトリで同期する状態を保てます。
顧客マスタや契約ステータスのように値が更新される可変テーブルについては、「snapshot」機能で変更履歴を記録できます。snapshotは、Type-2 Slowly Changing Dimension(値の変更履歴を新しい行として追加し、`dbt_valid_from`・`dbt_valid_to`列で有効期間を管理する手法)を可変ソーステーブル上に実装する仕組みです*6。過去のある時点でどの値が有効だったかを後から追跡する必要がある場合に使います。
下流での利用先を明示する機能として「exposure」もあります。exposureは、dbtが変換したモデルがどのダッシュボード・アプリケーション・機械学習パイプラインで使われているかをYAMLで宣言する機能です*1。あるモデルを変更した際に、どの下流成果物へ影響が及ぶかを`dbt docs generate`のDAG上で追跡できます。
dbt Core と dbt Cloud の違い
dbtには、オープンソースのCLIツールである「dbt Core」と、dbt Labsが提供するマネージドサービス「dbt Cloud」の2つの提供形態があります。dbt Coreはローカル環境やCI基盤から`dbt run`・`dbt test`等のコマンドを実行するツールであり、スケジューリングやWeb UIは付属しません。
これに対しdbt Cloudは、ブラウザベースのIDE、ジョブのスケジュール実行(日次・時間指定・繰り返し実行)、実行履歴の可視化、Slack・メール通知、ホスト型のドキュメントサイト、Discovery APIといった運用機能をまとめて提供します*7。GitHub・GitLab・Azure DevOpsとのネイティブ連携も備え、プルリクエスト上での自動テスト実行(CI機能)が組み込まれている点も、dbt Coreとの大きな違いです*7。
近年の動きとして、dbt LabsはRust製の新エンジン「dbt Fusion engine」を2025年5月にパブリックベータとして公開しました*8。Fusion engineは複数のSQL方言にネイティブ対応し、SQL検証・カラム単位の依存関係追跡(リネージュ)・実行前のインラインプレビューといった機能を提供する基盤で、dbt Platform(旧dbt Cloud)・VS Code拡張機能・専用CLIから利用できます*8。dbt Coreで小さく始め、運用規模の拡大に応じてdbt Cloud・Fusion engineへ段階的に移行する構成も選択肢になります。
対応DWHとadapter、CI連携の仕組み
dbtは単体でDWHに接続する機能を持たず、「adapter」と呼ばれるプラットフォーム別のプラグインを介して接続します。dbt Core利用時は`pip install dbt-snowflake`のように、対象DWHに対応するadapterパッケージを個別にインストールする構成です。公式ドキュメントには、dbt Labsの基準を満たし保守体制が確認された「Trusted adapter」として、Snowflake・BigQuery・Redshift・Databricks・Postgres等が列挙されています*9。主要なクラウドDWHは軒並みadapterが用意されており、DWHの選定とdbt導入は独立して検討できます。
CI(継続的インテグレーション)との連携も、dbt導入のメリットの1つです。dbt CloudのCI機能は、GitプロバイダからのPR作成・更新通知を検知し、変更の影響を受けるモデル・テストのみを一時的なスキーマ上でビルド・テストします*10。一時スキーマはPRのクローズ・マージ時に自動削除され、CI実行は本番用の実行枠を消費しない仕組みです*10。同じPRに新しいコミットが追加されると、実行中の古いCIジョブは自動的にキャンセルされます*10。
この仕組みにより、モデルのSQLを変更してマージする前に、影響範囲のテストが自動で走る体制を構築できます。dbt Coreのみで運用する場合は、GitHub Actions等の外部CI基盤にdbtコマンドの実行ステップを組み込む形で、同様の仕組みを自前で構築する必要があります。
内製でdbt運用を進める場合の必要スキルと工数
dbtによる変換基盤を内製で構築・運用するには、複数領域の知識が要ります。SQL自体の設計力に加え、Jinjaテンプレート構文とmacro(再利用可能なSQLコードブロックを定義する仕組み)の理解、DWH側のクエリコスト・パーティション設計の知識、Gitを使ったバージョン管理・レビュー運用の3領域が中心です。
設計を誤った場合の失敗コストとして代表的なのが、materialization(モデルをDWHにどう永続化するかの戦略)の選定ミスです。dbtにはview・table・incremental・ephemeralという主要な戦略があり、大規模テーブルにview戦略を適用すると、参照のたびに重いSELECT文が再実行されクエリコストが膨らみます。逆に、頻繁に定義が変わる小規模テーブルへ安易にincremental戦略(前回実行以降の差分のみを追加更新する方式)を適用すると、スキーマ変更時の再構築対応が複雑化します。
また、test・documentationを後回しにしてmodelだけを増やしていくと、モデル数の増加に伴いDAGが複雑化し、どのモデルがどの下流に影響するか把握できなくなる状態に陥りやすくなります。データエンジニアリングとSQL設計の両方に慣れた人材を確保できるかどうかが、内製運用の成否を分ける前提になります。
外注の委託範囲と発注準備
dbtによる変換基盤の構築・運用を外部パートナーに委託する場合、委託範囲を事前に切り分けておくと発注後の手戻りを抑えられます。想定される委託範囲は、dbtプロジェクトの初期設計(ディレクトリ構成・命名規則)、source・model・testの実装、materialization戦略の選定、dbt CoreとdbtCloudのどちらを採用するかの判断、CI連携の構築、運用ドキュメントの整備です。
発注準備として整理しておきたい情報は次の通りです。接続先DWHの種類とバージョン、既存のEL(抽出・ロード)ツールの構成、変換対象のテーブル数とデータ量の目安、更新頻度(日次・時間次等)、想定する利用者数とダッシュボードの数です。これらが曖昧なまま発注すると、adapter選定やジョブのスケジュール設計が確定できず、要件定義段階での後戻りが発生しやすくなります。
専門パートナーに依頼する場合と内製で進める場合の違いは、SQL・Jinja・DWH設計・Git運用を横断して理解する人材を新たに確保・育成する必要があるかどうかです。内製では、こうした複合的な知見を持つ人材の採用・育成にリードタイムを要します。外部委託では、複数のDWH・dbtプロジェクトを構築した経験を持つパートナーの知見を活用し、materialization戦略やCI設計での手戻りを抑える狙いがあります。
まとめ:dbt導入で確認すべき3つの判断軸
本稿では、dbtがELTのT(変換)をSQLとJinjaでどう管理するか、model・ref・source・test・snapshotの役割、dbt Coreとdbt Cloudの違い、CI連携の仕組みを整理しました。判断軸を3つに集約すると、第一に自社の変換要件(テーブル数・更新頻度・利用者数)がdbt Cloudの運用機能を必要とする規模かどうか、第二にtest・documentationを設計段階から組み込める体制があるかどうか、第三に内製と外注のどちらでリードタイムとクエリコストのリスクを抑えられるかです。
よくある質問
dbtとFivetranなどのELツールはどう役割が違いますか。
FivetranのようなELツールはデータの抽出・ロード(EL)を担い、dbtはロード後のDWH内での変換(T)を担います*1。両者は競合するものではなく、ELT全体のパイプラインの中で前工程と後工程を分担する組み合わせで使われます。
dbt Coreとdbt Cloud、どちらを選べばよいですか。
スケジュール実行・CI連携・Web UIをまとめて使いたい場合はdbt Cloudが適しています*7。既存のCI基盤やオーケストレーションツールを既に運用しており、コマンド実行のみで足りる場合はdbt Coreを自前の基盤に組み込む構成も選択肢になります。
materializationはどう使い分けますか。
参照頻度が低い小規模なモデルはview、頻繁に参照される中規模モデルはtable、大規模で増分更新が可能なモデルはincrementalを使うのが基本的な考え方です。dbt公式ドキュメントもview・table・incremental・ephemeralの4種類を主要な戦略として説明しています*1。
testやdocsは後から追加してもよいですか。
後から追加すること自体は可能ですが、モデル数が増えるほど依存関係の把握が難しくなるため、model実装と同時にtest・descriptionを書き加える運用を初期段階から定着させることが望ましいです*4。
外注する場合、どこまでを委託範囲にすればよいですか。
プロジェクトの初期設計・source/model/testの実装・materialization戦略の選定・CI連携の構築までを委託範囲とするのが一般的です。運用開始後のモデル追加をどちらが担うかは、発注前に切り分けておくことが手戻りを防ぎます。
著者:テレリモ総研編集部 鈴木 亮佑
ご不明な点はお問い合わせフォームからもご連絡いただけます。
- *1 出典:dbt Labs「About dbt models」dbt Developer Hub(https://docs.getdbt.com/docs/build/models)
- *2 出典:dbt Labs「ref」dbt Developer Hub(https://docs.getdbt.com/reference/dbt-jinja-functions/ref)
- *3 出典:dbt Labs「Add sources to your DAG」dbt Developer Hub(https://docs.getdbt.com/docs/build/sources)
- *4 出典:dbt Labs「Add data tests to your DAG」dbt Developer Hub(https://docs.getdbt.com/docs/build/data-tests)
- *5 出典:dbt Labs「Documentation」dbt Developer Hub(https://docs.getdbt.com/docs/collaborate/documentation)
- *6 出典:dbt Labs「Add snapshots to your DAG」dbt Developer Hub(https://docs.getdbt.com/docs/build/snapshots)
- *7 出典:dbt Labs「About continuous integration jobs」dbt Developer Hub(https://docs.getdbt.com/docs/deploy/continuous-integration)
- *8 出典:dbt Labs「About dbt Fusion engine」dbt Developer Hub(https://docs.getdbt.com/docs/fusion/about-fusion)
- *9 出典:dbt Labs「Trusted adapters」dbt Developer Hub(https://docs.getdbt.com/docs/trusted-adapters)
- *10 出典:dbt Labs「About continuous integration jobs」dbt Developer Hub(https://docs.getdbt.com/docs/deploy/continuous-integration)