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으로 수정하는 게 안전하기 때문.