Database Migration

"Migration"은 DB 맥락에서 두 가지 의미로 쓰인다.


1. Schema Migration

DB 스키마 변경을 버전 관리하는 것. 현업에서 "migration 추가해주세요"라고 하면 대부분 이 의미다.

테이블 생성, 컬럼 추가/삭제, 인덱스 변경 등 스키마 변경을 파일 단위로 관리하고, 순서대로 적용(up) / 롤백(down)할 수 있다. 코드의 git처럼 DB 스키마에 대한 변경 이력을 추적하는 개념.

Migration 파일 예시

migrations/
├── V001_create_users_table.sql
├── V002_add_email_column.sql
└── V003_create_orders_table.sql

각 파일이 하나의 migration이고, 번호 순서대로 적용된다.

Up / Down

-- V002_add_email_column.up.sql
ALTER TABLE users ADD COLUMN email VARCHAR(255);

-- V002_add_email_column.down.sql
ALTER TABLE users DROP COLUMN email;
  • Up: 스키마를 다음 버전으로 변경
  • Down: 이전 버전으로 롤백

동작 방식

대부분의 migration 도구는 DB에 schema_migrations 같은 메타 테이블을 만들어 현재 적용된 버전을 추적한다.

+-------------------+
| schema_migrations |
+-------------------+
| version | applied |
|---------|---------|
| 001     | true    |
| 002     | true    |
| 003     | false   |  ← 다음 migrate 실행 시 적용
+-------------------+

주요 도구

언어/프레임워크 도구
Go golang-migrate, goose, atlas
Python/Django Django ORM built-in (manage.py migrate)
Ruby/Rails ActiveRecord Migration
Java/Kotlin Flyway, Liquibase
DB 독립적 Flyway, Liquibase

Django 예시

Django는 모델 정의에서 migration 파일을 자동 생성한다.

python manage.py makemigrations   # 모델 변경을 감지하여 migration 파일 생성
python manage.py migrate          # 미적용 migration을 DB에 적용
python manage.py migrate app 0002 # 특정 버전으로 롤백

golang-migrate 예시

# migration 파일 생성
migrate create -ext sql -dir migrations -seq create_users_table

# 적용
migrate -path migrations -database "mysql://user:pass@tcp(localhost:3306)/db" up

# 롤백
migrate -path migrations -database "mysql://user:pass@tcp(localhost:3306)/db" down 1

2. Data Migration

기존 시스템에서 새 시스템으로 데이터를 이관하는 것. 스키마 변경이 아닌 데이터 자체의 이동.

  • DB 교체 (Oracle → PostgreSQL)
  • 서비스 분리 (모놀리스 → 마이크로서비스)
  • 레거시 테이블 구조 변경 후 데이터 재적재

Schema Migration 주의사항

  • Migration 파일은 한번 적용된 후에는 수정하지 않는다. 새 migration을 추가하는 것이 원칙.
  • 운영 DB에 적용할 때는 lock 시간을 고려해야 한다. 대형 테이블에 ALTER TABLE은 장시간 lock을 잡을 수 있다.
  • Down migration은 작성하지 않는 팀도 많다. 운영에서 롤백보다 새 migration으로 수정하는 게 안전하기 때문.