Delta Lakeはデフォルトでスキーマエンフォースメント(スキーマ検証)を行い、テーブル定義に合わないデータの書き込みを拒否します。 しかし実運用では、ソースシステムの変更に伴ってカラムが追加されたり、型が変わったりすることがあります。 スキーマエボリューションは、こうした変更にテーブルを柔軟に追従させるための仕組みです。
この記事では、スキーマエンフォースメントのデフォルト挙動、mergeSchemaとoverwriteSchemaの違い、 Auto Loaderのスキーマエボリューションモード、MERGE INTOでのスキーマエボリューション、 Column Mapping、パーティション列の制約を整理します。
Delta Lakeのテーブルに書き込む際、書き込みデータのスキーマがテーブルのスキーマと一致しない場合、 デフォルトではエラーが発生して書き込みが拒否されます。これがスキーマエンフォースメントです。
-- テーブル定義
CREATE TABLE events (event_id BIGINT, event_type STRING, amount DECIMAL(10,2));
-- 新しいカラム "region" を含むデータを書き込もうとするとエラー
INSERT INTO events
SELECT 1 AS event_id, 'purchase' AS event_type, 99.99 AS amount, 'APAC' AS region;
-- AnalysisException: cannot resolve 'region' given input columns| 比較軸 | mergeSchema | overwriteSchema |
|---|---|---|
| 目的 | 既存スキーマに新カラムを追加 | スキーマを完全に置換 |
| 既存カラム | 維持される | 書き込みデータのスキーマで上書き |
| カラム追加 | 可能 | 可能 |
| カラム削除 | 不可 | 可能(新スキーマに含まれないカラムは消える) |
| 型の拡張 | 可能(INT→BIGINTなど安全な拡張のみ) | 可能(任意の型変更) |
| 型の縮小 | 不可 | 可能(ただしデータ損失リスクあり) |
| writeのmode | append / overwrite | overwrite のみ |
| 破壊性 | 非破壊的 | 破壊的(既存データとの互換性喪失の可能性) |
# DataFrameの書き込み時にmergeSchemaを有効化
(df.write
.format("delta")
.mode("append")
.option("mergeSchema", "true")
.saveAsTable("events")
)
# SQLでセッション単位で有効化
SET spark.databricks.delta.schema.autoMerge.enabled = true;
# テーブルプロパティで永続的に有効化
ALTER TABLE events
SET TBLPROPERTIES ('delta.autoOptimize.autoCompact' = 'true');mergeSchemaが許可する操作と許可しない操作の境界を理解することが試験で重要です。
| 操作 | mergeSchemaで可能? | 備考 |
|---|---|---|
| 新しいカラムの追加 | はい | 最も一般的な用途 |
| 型の拡張(INT → BIGINT) | はい | 安全な拡張のみ(BYTE→SHORT→INT→BIGINT) |
| 型の縮小(BIGINT → INT) | いいえ | データ損失リスクがあるため不可 |
| カラムの削除 | いいえ | overwriteSchemaまたはColumn Mappingが必要 |
| カラム名の変更 | いいえ | Column Mapping機能を使う |
| ネストされた構造体へのフィールド追加 | はい | Struct型の内部にフィールドを追加可能 |
# mode("overwrite") + overwriteSchema でスキーマを完全置換
(df.write
.format("delta")
.mode("overwrite")
.option("overwriteSchema", "true")
.saveAsTable("events")
)overwriteSchemaは破壊的な操作です。テーブルの既存データと互換性がなくなる可能性があるため、 本番環境では慎重に使うべきです。Time Travelで元のスキーマに戻すことは可能ですが、 新スキーマで書き込まれたデータは旧スキーマでは読めません。
Auto Loaderは独自のスキーマ推論・エボリューション機能を持っています。cloudFiles.schemaEvolutionMode で挙動を制御します。
| モード | 新カラム検知時の挙動 | 用途 |
|---|---|---|
| addNewColumns | 新カラムを自動追加してストリーム継続 | スキーマ変更が頻繁な環境 |
| failOnNewColumns | 新カラム検知でストリーム停止 | 厳密なスキーマ管理が必要な環境 |
| rescue | スキーマ外データを _rescued_data カラムに退避 | データ損失を防ぎたい環境 |
| none | スキーマエボリューションを無効化 | 固定スキーマの取り込み |
# Auto Loader + スキーマエボリューション
(spark.readStream
.format("cloudFiles")
.option("cloudFiles.format", "json")
.option("cloudFiles.schemaEvolutionMode", "addNewColumns")
.option("cloudFiles.schemaLocation", "/schema/events")
.load("/landing/events/")
.writeStream
.option("checkpointLocation", "/checkpoint/events")
.option("mergeSchema", "true")
.table("bronze.events")
)MERGE INTO でもスキーマエボリューションが可能です。 ソースデータに新しいカラムがある場合、Spark設定を有効にするとターゲットテーブルにカラムが自動追加されます。
-- セッションレベルで有効化
SET spark.databricks.delta.schema.autoMerge.enabled = true;
-- ソースに "loyalty_tier" という新カラムがある場合
-- ターゲットに自動的に loyalty_tier カラムが追加される
MERGE INTO silver.customers t
USING staging.updates s
ON t.customer_id = s.customer_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;UPDATE SET *とINSERT *を使う場合のみスキーマエボリューションが動作します。 カラムを個別に指定するUPDATE SET t.col = s.col形式では、新カラムは追加されません。
Delta Lake 2.0以降では、Column Mapping機能によりカラム名の変更やカラムの削除がALTER TABLEで可能になりました。
-- Column Mappingの有効化
ALTER TABLE events SET TBLPROPERTIES (
'delta.columnMapping.mode' = 'name',
'delta.minReaderVersion' = '2',
'delta.minWriterVersion' = '5'
);
-- カラム名の変更
ALTER TABLE events RENAME COLUMN event_type TO event_category;
-- カラムの削除
ALTER TABLE events DROP COLUMN temp_column;スキーマエボリューションにおいて、パーティション列には特別な制約があります。
パーティション構造を根本的に変更する場合は、テーブルの再作成(CTAS)が必要です。 これはLiquid Clusteringへの移行動機の一つでもあります。
Data Engineer Associate
問題 1
Bronze層のテーブルに新しいカラム 'utm_source' が含まれるJSONファイルが到着し始めた。Silver層のDelta Tableにはこのカラムがまだない。既存データを壊さずに新カラムを自動追加するには、どのオプションを使うべきか。
正解: A
mergeSchemaは既存スキーマに新カラムを追加するオプションで、既存データには影響しません。overwriteSchemaはスキーマ全体を上書きするため既存データとの互換性が壊れる可能性があります。手動ALTER TABLEも機能しますが「自動追加」の要件を満たしません。DROPは論外です。
mergeSchemaとoverwriteSchemaの違いは?
mergeSchemaは既存スキーマに新しいカラムを追加する(既存カラムは維持)。overwriteSchemaは既存スキーマを完全に上書きする(カラムの削除・型変更も可能)。通常のETLではmergeSchema、テーブル構造を根本的に作り直す場合にoverwriteSchemaを使います。
スキーマエンフォースメントとスキーマエボリューションの関係は?
スキーマエンフォースメントはDelta Lakeのデフォルト挙動で、テーブルのスキーマに合わないデータの書き込みを拒否します。スキーマエボリューションはこの制約を緩和し、新しいカラムの追加を許可するオプションです。エンフォースメントが「門番」、エボリューションが「門を広げる操作」と考えると分かりやすいです。
試験でスキーマエボリューションはどう出題されますか?
Data Engineer Associateで頻出です。mergeSchemaのオプション指定方法(.option('mergeSchema', 'true')やSpark設定spark.databricks.delta.schema.autoMerge.enabled)、Auto Loaderのスキーマエボリューションモード(addNewColumns/failOnNewColumns/rescue/none)、MERGEステートメントでのスキーマエボリューション有効化が主な出題範囲です。overwriteSchemaが破壊的操作であることも問われます。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Databricks資格一覧|全7試験・難易度・勉強法
Databricks認定資格全7試験の一覧・難易度・出題範囲・合格ラインを徹底解説。2026年最新版の公式試験ガイドに準...
Databricks試験の難易度ランキング|全7資格を徹底比較
Databricks認定全7試験の難易度をランキング形式で徹底比較。合格率・学習時間・出題傾向から難易度を分析。...
Databricks資格の勉強方法|最短合格ルートと学習時間の目安
Databricks認定資格に最短で合格するための勉強方法を完全ガイド。公式リソース・問題集・学習スケジュールを徹底解説...
Databricks Data Engineer Associate完全解説|出題範囲・問題例・合格戦略
Databricks Certified Data Engineer Associate試験を徹底解説。5つの出題ドメイ...
Databricks Data Engineer Professional完全解説|上級試験の攻略法
Databricks Certified Data Engineer Professional試験を徹底解説。10の出題...