1317 words
7 minutes
[DE Design Pattern]09-03 Schema Coompatibility Enforcer

3. Schema Consistency I — Schema Compatibility Enforcer#

01. Pattern Overview#

  • Schema Compatibility Enforcer는 스키마 변경 자체를 통제하는 패턴.
  • 데이터 producer가 스키마를 변경할 때, 그 변경이 기존 consumer를 깨뜨리지 않는지를 호환성 규칙으로 검증

02. 3가지 Enforcement 모드#

1) External Service/Library 모드 — Schema Registry 같은 외부 서비스가 스키마를 버전 관리하고, producer가 데이터를 쓰기 전에 스키마를 검증한다. 호환성 규칙을 명시적으로 설정

# Kafka Schema Registry를 통한 스키마 등록 및 호환성 검증
# 스키마 정의 (Avro)
schema = {
"type": "record",
"namespace": "com.example",
"name": "Visit",
"fields": [
{"name": "visit_id", "type": "string"},
{"name": "event_time", "type": "int", "logicalType": "date"}
]
}
# Schema Registry에 FORWARD compatibility로 설정된 상태에서
# producer가 visit_id 필드를 제거한 새 스키마로 쓰려고 시도하면:
# → 409 에러 발생
# "Schema being registered is incompatible with an earlier schema"
# "READER_FIELD_MISSING_DEFAULT_VALUE: visit_id has no default
# value and is missing in the new schema"

2) Implicit with Inserts 모드 — Delta Lake, RDBMS 같은 저장소가 테이블 생성 시 정의된 스키마와 다른 데이터를 쓰려고 하면 자동으로 거부.

# Delta Lake implicit schema enforcement
# 기존 테이블 스키마: visit_id(string), page(string), event_time(long)
# producer가 ad_id 컬럼을 추가한 데이터를 쓰려고 시도
new_data = spark.createDataFrame([
("v1", "/home", 1700000000, "ad_123")
], ["visit_id", "page", "event_time", "ad_id"])
new_data.write.format("delta").mode("append").save(table_path)
# → AnalysisException 발생
# "A schema mismatch detected when writing to the Delta table"
# Table schema: visit_id, page, event_time
# Data schema: visit_id, page, event_time, ad_id

Delta Lake는 명시적으로 mergeSchema 옵션을 켜지 않는 한, 스키마 변경을 허용하지 않는다.

3) Event-driven for DDL 모드 — PostgreSQL, SQL Server 같은 RDBMS에서 DDL 이벤트 트리거를 걸어, DROP COLUMN이나 RENAME COLUMN 같은 스키마 변경 시도를 가로채서 검증하거나 롤백

# PostgreSQL: DDL event trigger로 스키마 변경 방지
# (SQL로 정의하지만 개념 이해를 위해 pseudo-code로 표현)
# CREATE EVENT TRIGGER prevent_column_drop
# ON ddl_command_start
# WHEN TAG IN ('ALTER TABLE')
# EXECUTE FUNCTION check_schema_compatibility();
# 또는 더 간단한 방법: ALTER TABLE 권한 자체를 부여하지 않음
# REVOKE ALTER ON TABLE visits FROM data_producer_role;

04. 호환성 모드 (Compatibility Modes)#

Schema Registry를 사용할 때 설정할 수 있는 호환성 모드는 크게 3가지이며, 각각 transitive/nontransitive 변형이 있다.

Backward Compatibility — 새 스키마를 쓰는 consumer가 이전 스키마로 생산된 데이터를 읽을 수 있다. 허용 액션: 필드 삭제, optional 필드 추가.

Forward Compatibility — 이전 스키마를 쓰는 consumer가 새 스키마로 생산된 데이터를 읽을 수 있다. 허용 액션: 필드 추가, optional 필드 삭제.

Full Compatibility — backward + forward 모두 보장. 허용 액션: optional 필드 추가/삭제만 가능.

05. Transitive vs Nontransitive#

Nontransitive — 직전 버전과의 호환성만 검증 (v(n) ↔ v(n-1)).

Transitive — 모든 이전/이후 버전과의 호환성을 검증 (v(n) ↔ v(0), v(1), …, v(n-1)).

# Backward compatibility에서 transitive가 깨지는 시나리오
# v0: order_id LONG REQUIRED
# v1: order_id LONG REQUIRED, amount DOUBLE DEFAULT 0.0 ← optional 추가 (OK)
# v2: order_id LONG REQUIRED, amount DOUBLE REQUIRED ← default 제거 (?)
# Nontransitive 관점 (v2 ↔ v1만 비교):
# v2 consumer가 v1 데이터를 읽을 때 → amount에 default 0.0이 있으므로 OK ✓
# Transitive 관점 (v2 ↔ v0도 비교):
# v2 consumer가 v0 데이터를 읽을 때 → amount 필드 자체가 없고 default도 없음 ✗
# → 호환성 위반!

v1 → v2 진화는 nontransitive에서는 유효하지만, transitive에서는 v0과의 호환성이 깨져서 거부된다. 이것이 transitive 모드가 더 엄격하지만 더 안전한 이유다.

Consequences#

Interaction overhead — 특히 external service 모드에서, producer는 매 레코드마다 Schema Registry에 최신 스키마 버전을 확인해야 하므로 추가 네트워크 비용이 발생

Schema evolution 난이도 상승 — 호환성 규칙 때문에 필드 rename 같은 단순한 작업도 “새 필드 추가 → 구 필드 deprecate” 같은 우회 경로 필요


Concept

  • Schema Compatibility Enforcer : 스키마 변경이 기존 consumer를 깨뜨리지 않도록 호환성 규칙으로 통제하는 패턴
  • External Service 모드 : Schema Registry 같은 외부 서비스가 스키마를 버전 관리하고 호환성을 검증. 명시적 호환성 모드 설정 가능
  • Implicit with Inserts 모드 : Delta Lake, RDBMS가 현재 테이블 스키마와 다른 데이터 쓰기를 자동 거부. 별도 호환성 모드 없음
  • Event-driven for DDL 모드 : DDL 이벤트 트리거로 스키마 변경 시도를 가로채서 검증/롤백. PostgreSQL, SQL Server 지원
  • Backward Compatibility : 새 스키마 consumer가 이전 스키마 데이터를 읽을 수 있음. 필드 삭제, optional 필드 추가 허용
  • Forward Compatibility : 이전 스키마 consumer가 새 스키마 데이터를 읽을 수 있음. 필드 추가, optional 필드 삭제 허용
  • Full Compatibility : backward + forward 모두 보장. optional 필드 추가/삭제만 가능
  • Transitive Compatibility : 모든 과거/미래 스키마 버전과 호환성을 보장. Nontransitive보다 엄격하지만 안전
  • Nontransitive Compatibility : 직전 버전과의 호환성만 보장. 더 유연하지만 버전 간 간접적 비호환 가능성 존재
  • Schema Registry : Apache Kafka 생태계에서 스키마를 중앙 관리하고 호환성을 검증하는 서비스. Confluent Schema Registry가 대표적

[DE Design Pattern]09-03 Schema Coompatibility Enforcer
https://yjinheon.netlify.app/posts/02de/00-de-design-pattern/09_data_quality/09-03-schema-compatibiliy/
Author
Datamind
Published at
2026-04-03
License
CC BY-NC-SA 4.0