By default, Delta Lake performs schema enforcement (schema validation) and rejects writes whose data does not match the table definition. In real-world operations, however, columns get added or types change as source systems evolve. Schema evolution is the mechanism that lets a table flexibly keep up with those changes.
This article walks through the default behavior of schema enforcement, the difference between mergeSchema and overwriteSchema, Auto Loader's schema evolution modes, schema evolution in MERGE INTO, Column Mapping, and the constraints on partition columns.
When you write to a Delta Lake table, if the schema of the incoming data does not match the table schema, the write is rejected with an error by default. That is schema enforcement.
-- テーブル定義
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| Aspect | mergeSchema | overwriteSchema |
|---|---|---|
| Purpose | Add new columns to the existing schema | Completely replace the schema |
| Existing columns | Preserved | Overwritten with the incoming data's schema |
| Column addition | Allowed | Allowed |
| Column deletion | Not allowed | Allowed (columns not in the new schema disappear) |
| Type widening | Allowed (only safe widenings such as INT → BIGINT) | Allowed (any type change) |
| Type narrowing | Not allowed | Allowed (but risks data loss) |
| write mode | append / overwrite | overwrite only |
| Destructiveness | Non-destructive | Destructive (may break compatibility with existing data) |
# 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');Understanding exactly which operations mergeSchema does and does not allow is important on the exam.
| Operation | Possible with mergeSchema? | Notes |
|---|---|---|
| Adding a new column | Yes | The most common use case |
| Type widening (INT → BIGINT) | Yes | Only safe widenings (BYTE → SHORT → INT → BIGINT) |
| Type narrowing (BIGINT → INT) | No | Disallowed because of data loss risk |
| Dropping a column | No | Requires overwriteSchema or Column Mapping |
| Renaming a column | No | Use the Column Mapping feature |
| Adding fields to nested structs | Yes | Fields can be added inside Struct types |
# mode("overwrite") + overwriteSchema でスキーマを完全置換
(df.write
.format("delta")
.mode("overwrite")
.option("overwriteSchema", "true")
.saveAsTable("events")
)overwriteSchema is a destructive operation. Because it can break compatibility with the table's existing data, use it carefully in production. You can use Time Travel to roll back to the previous schema, but data written under the new schema cannot be read under the old one.
Auto Loader has its own schema inference and evolution features. cloudFiles.schemaEvolutionMode controls the behavior.
| Mode | Behavior when a new column is detected | When to use |
|---|---|---|
| addNewColumns | Automatically add the new column and continue the stream | Environments where the schema changes frequently |
| failOnNewColumns | Stop the stream when a new column is detected | Environments that require strict schema control |
| rescue | Send off-schema data to a _rescued_data column | Environments where you want to avoid losing data |
| none | Disable schema evolution | Ingestion with a fixed schema |
# 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")
)Schema evolution also works in MERGE INTO. When the source data has a new column and the Spark setting is enabled, the column is automatically added to the target table.
-- セッションレベルで有効化
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 *;Schema evolution only kicks in when you use UPDATE SET * and INSERT *. If you specify columns individually with UPDATE SET t.col = s.col, new columns will not be added.
From Delta Lake 2.0 onward, the Column Mapping feature makes it possible to rename and drop columns using 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;Partition columns have special constraints under schema evolution.
If you need to fundamentally change the partition structure, you have to rebuild the table (CTAS). This is also one of the motivations for migrating to Liquid Clustering.
Data Engineer Associate
問題 1
JSON files containing a new column 'utm_source' have started arriving in the Bronze layer. The Silver layer Delta table does not yet have this column. Which option should you use to automatically add the new column without breaking existing data?
正解: A
mergeSchema is the option that adds a new column to the existing schema without affecting existing data. overwriteSchema overwrites the whole schema and can break compatibility with existing data. A manual ALTER TABLE would work but does not meet the 'automatic addition' requirement. DROP is out of the question.
What is the difference between mergeSchema and overwriteSchema?
mergeSchema adds new columns to the existing schema while keeping existing columns intact. overwriteSchema completely replaces the existing schema (allowing column deletion and type changes). Use mergeSchema for normal ETL work, and overwriteSchema only when you need to rebuild the table structure from scratch.
How are schema enforcement and schema evolution related?
Schema enforcement is Delta Lake's default behavior, rejecting writes whose data does not match the table schema. Schema evolution relaxes that constraint with an opt-in option that allows new columns to be added. Think of enforcement as the gatekeeper, and evolution as the action that widens the gate.
How is schema evolution tested on the exam?
This is a frequent topic on Data Engineer Associate. The main areas tested are: how to enable mergeSchema (the .option('mergeSchema', 'true') write option and the spark.databricks.delta.schema.autoMerge.enabled Spark config), the Auto Loader schema evolution modes (addNewColumns / failOnNewColumns / rescue / none), and how to enable schema evolution inside MERGE statements. The fact that overwriteSchema is a destructive operation also comes up.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
Databricks Certifications: All 7 Exams, Difficulty & Study Plan (2026)
Complete guide to all 7 Databricks certifications — Data Eng...
Databricks Exam Difficulty Ranking: All 7 Certs Compared (2026)
Every Databricks certification ranked by difficulty, with st...
Databricks Study Guide: Fastest Pass Route & Time Estimates (2026)
How to pass Databricks certifications efficiently. Official ...
Databricks Data Engineer Associate: Complete Guide (2026)
Domain-by-domain breakdown of the Databricks Certified Data ...
Databricks Data Engineer Professional: Complete Guide (2026)
Tactics for the Databricks Certified Data Engineer Professio...