ふくふくHukuhuku Inc.
EP.05Incident 10分公開: 2026-05-10

スキーマドリフト:「カラムが知らないうちに増えた・型が変わった」事件

ソース側で気軽に追加された1カラムで、下流の ETL・dbt・ダッシュボードが連鎖的に壊れる。検知・自動対応・予防の3層対策。

#スキーマ#ETL#dbt#データ品質
シェア

「営業システム側が機能追加で `notes` カラム追加しました」── 開発側にとっては小さな変更が、データ基盤側にはカスケード障害を引き起こす。スキーマドリフトは静かに進行し、ある日突然 が失敗します。

あの時こうすれば良かった、と思う症状

・営業から「先週から数字が変です」 / ・ETL ログに `column not found` / ・突然 NULL 比率が増えた / ・「列の意味が変わったらしい」(ID が再利用された等)

起きる仕組み(よくあるパターン)

  • カラム追加:ソース側で気軽に追加。SELECT * で取ってると問題なし、明示列で取ってると古い ETL でも動く(が新カラムは取れない)
  • カラム削除:明示参照していた場所が即死
  • 型変更:`int → string` 等で JOIN や集計が壊れる(特にゼロパディング `001` を削った瞬間)
  • 意味の変更:`status: 1 = 進行中` だったのが `1 = 完了` に逆転
  • 主キーの再利用:削除されたユーザID が新規ユーザに再付与される

調査手順

bigquery:直近の INSERT カラム数の変化を見る
SQL
-- ソース → ステージングテーブルの行数・NULL率の異常検知SELECT  DATE(loaded_at) AS day,  COUNT(*) AS rows,  COUNTIF(notes IS NULL) / COUNT(*) AS null_ratio_notes,  COUNTIF(status_v2 IS NULL) / COUNT(*) AS null_ratio_status_v2FROM staging.ordersWHERE loaded_at > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)GROUP BY dayORDER BY day DESC;
  • INFORMATION_SCHEMA.COLUMNS の差分:1週間ごとのカラム一覧を保存して diff
  • dbt schema test:`unique`/`not_null`/`accepted_values` で型・値の前提が崩れていないか毎晩
  • Great Expectations / Soda:データ品質ルールで「列の存在」「型」「分布」を継続検査
  • ソース側のリリースノート:開発チームに「列追加したら notify ください」を文化化

短期対処

  • SELECT * を一時的に避難:明示列指定で「想定列だけ取る」に切り替え
  • 型キャスト追加:`SAFE_CAST` で fail を NULL に
  • dbt の `column_types`:型強制で予期せぬ拡張を検知
  • バックアップから復元:壊れる前のデータで再ロード

中長期対策

  • Schema Registry(Confluent / Avro):ソース側がスキーマを宣言、互換性違反は で止める
  • 自動カラム追加 + alert:スキーマドリフトを検知したらカラム自動追加 + 通知
  • DataHub / OpenMetadata:データカタログでカラムの意味を管理し、属人化を解消
  • 契約テスト(Data Contract):ソース側と分析側の「合意」を yaml で明文化
  • lint ルール:`SELECT *` 禁止(前章でも触れた、スキーマドリフトと相性悪し)

ふくふくの進め方

ソース・ステージング・marts の全テーブルに schema test + freshness test を1週間で当てる、というのが入りの提案です。1ヶ月後にはスキーマドリフト由来の障害は半減以下が目安。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp