Schema Migration — 본질, 유형 및 데이터베이스 스키마 마이그레이션 도구

저자: IT Sectr 게시일: 2026-06-15 읽는 시간: 10 분

Schema Migration은 애플리케이션 개발 중 데이터베이스 구조 변경을 버전 관리하는 프로세스입니다. 각 변경은 스크립트로 설명되며 dev, staging 그리고 production 환경에 순차적으로 적용됩니다. JetBrains (2025)에 따르면, 78% 팀이 스키마 마이그레이션 도구를 사용하고, 34%는 여전히 콘솔을 통해 매뉴얼로 데이터베이스를 편집합니다 — 스키마 평차의 주요 원인입니다. 마이그레이션을 자동화하면 인간 실수가 제거되고 환경 간 구조적 일관성이 보장됩니다.

주요 포인트

  • Schema Migration — 스크립트를 통한 데이터베이스 구조의 버전 변경.
  • Flyway — 간단한 SQL 마이그레이션 스크립트로 Java/Kotlin 용 도구.
  • Liquibase — 롤백 지원이 있는 XML/YAML/JSON 형식.
  • Alembic — 자동 생성이 있는 SQLAlchemy 용 Python 도구.
  • 스키마 괵동 — 마이그레이션 없이 여러 개발자가 작업할 때 주요 문제.

Schema Migration이란

Schema Migration은 다양한 환경에 순차적으로 적용되는 버전 파일을 통해 데이터베이스 구조 변경을 관리하는 실무입니다. 각 파일에는 SQL 명령어 집합이 포함됩니다: 테이블 생성, 컬럼 추가, 인덱스 수정, 제약 조건 업데이트. 마이그레이션 도구는 적용된 버전을 추적하고 각 변경이 정확히 한 번만 실행되도록 보장합니다.

테이블 내용을 전솔하는 Data Migration과 달리, Schema Migration은 구조(DDL 작업)만 관리합니다. 이것은 근본적인 차이점입니다: Schema Migration이 Data Migration보다 먼저 실행되어 대상 스키마를 만들고, 그 다음에 Data Migration이 데이터를 로드합니다. Redgate (2024)에 따르면, 프로덕션 데이터베이스의 62% 사고가 마이그레이션 스크립트 없이 수동으로 스키마를 변경해서 발생합니다.

마이그레이션 버전 관리

각 Schema Migration은 고유 식별자를 받습니다 — 보통 버전 (V1, V2) 또는 타임스탬프입니다. 도구는 별도 테이블(flyway_schema_history, alembic_version)에 적용된 마이그레이션 목록을 저장합니다. 시작할 때 classpath의 파일과 목록을 비교하여 새로운 것만 적용합니다. 액션 재실행 불변성은 중요한 특성입니다: 재실행해도 부작용이 발생하지 않습니다.

스키마 변경 유형

일반적인 Schema Migration 작업: 테이블 생성 (CREATE TABLE), 컬럼 추가 (ALTER TABLE ADD COLUMN), 타입 변경, 인덱스 생성, 외래키 추가, 시퀀스 업데이트. 더 복잡한 마이그레이션은 데이터를 유지하면서 컬럼 이름 변경, 테이블을 여러 개로 분할, 샤드 간 스키마 복제를 포함합니다.

데이터베이스 스키마 마이그레이션이 필요한 이유

Schema Migration이 없으면 개발자는 데이터베이스를 수동으로 변경합니다 — 콘솔에서 DDL을 편집하고, dev 환경에서 컬럼을 추가하고, 기억엄으로 staging에 복사합니다. 결과: 환경 간 스키마 평차, 배포 중 변경 손실, 그리고 프로덕션에서 마이그레이션 실패. Schema Migration은 세 가지 주요 문제를 해결합니다: 일관성, 재현성, 그리고 감사.

환경 간 일관성

데이터베이스 구조가 코드로 설명되면 dev, staging, 그리고 프로덕션에서 동일합니다. 개발자가 변경 적용을 잊을 수 없습니다 — 도구가 누락된 모든 마이그레이션을 순차적으로 실행합니다. 프로덕션에서 컬럼이 없는데 코드가 필요로 하면 애플리케이션이 오류로 실패합니다. 자동 검증이 이 시나리오를 제거합니다.

새 개발자를 위한 재현성

새 팀 구원이 flyway migrate를 실행하면 수 초 내에 현재 스키마를 홝으며 얻습니다 — 프로덕션 덤프나 수동 DDL 쿼리가 필요 없습니다. 이것은 각 서비스가 자체 데이터베이스를 가지고 스키마가 수십 개의 마이그레이션으로 구축되는 마이크로서비스 아키텍처에서 특히 중요합니다. 완전한 재현성이 온보디옵 시간을 몇 일에서 몇 분으로 줄임니다.

변경 감사

각 Schema Migration은 애플리케이션 코드와 함께 버전 관리 시스템에 저장됩니다. Pull Request를 열고 스키마 변경의 정확한 SQL 명령어를 보고 코드 리뷰를 수행할 수 있습니다. 사고 발생 시 어떤 마이그레이션이 마지막으로 적용되었고 누가 작성했는지 쉽게 파악할 수 있습니다. Git 이력은 프로젝트 전 기간의 데이터베이스 변경에 대한 완전한 추적을 제공합니다.

스키마 마이그레이션 도구

다양한 언어와 플랫폼을 위한 수십 개의 Schema Migration 도구가 있습니다. 선택은 기술 스택, 마이그레이션 설명 형식 그리고 롤백 요구사항에 따라 달라집니다. 주요 카테고리와 인기 도구를 살펴보겠습니다.

도구언어형식롤백
FlywayJava, Kotlin, ScalaSQL, Java별도 스크립트 통해
LiquibaseJava, Groovy, KotlinXML, YAML, JSON, SQL내장 롤백
AlembicPythonPython, SQL자동 생성 다운그레이드
Active RecordRubyRuby DSLrevert 통해
Entity FrameworkC#C# Fluent API자동 생성

도구 선택 방법

Java/Kotlin 스택에는 — Flyway 가장 가벌고 예측 가능합니다. 잧은 간격으로 롤백이 필요한 프로젝트에는 — Liquibase를 검토하세요. Python/Django에는 — Alembic이 표준 SQLAlchemy 도구입니다. DevOps 엔지니어가 없는 스타트업에는 — 가장 설정이 적은 도구를 선택하세요: Flyway는 스크립트 파일과 migrate 명령어만 필요합니다.

상용 솔루션

오픈 소스 도구 외에도 상용 솔루션(Redgate SQL Change Automation, Datical DB, DBmaestro)이 있습니다. 이들은 시각적 스키마 비교, 자동 괵동 해결, CI/CD 파이프라인 연동을 제공합니다. 그러나 대부분의 프로젝트에서는 FlywayAlembic이 추가 라이선스 없이 100% 요구사항을 충족합니다.

Flyway로 마이그레이션

Flyway로 Kotlin에서 실용적인 Schema Migration 예제를 살펴보겠습니다. PostgreSQL 데이터베이스에 orders 테이블을 추가하는 마이그레이션을 만들겠습니다. Flyway는 flyway_schema_history 테이블을 자동으로 생성하고 적용된 버전을 추적합니다.

sql
-- V1__Create_Orders_Table.sql
CREATE TABLE orders (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id         UUID NOT NULL,
    total_amount    DECIMAL(10,2) NOT NULL,
    currency        VARCHAR(3) NOT NULL DEFAULT 'USD',
    status          VARCHAR(20) NOT NULL DEFAULT 'pending',
    created_at     TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id)
);

dataSource 구성을 통해 Kotlin 프로젝트에 Flyway 연결. 설정 후 flyway:migrate 명령어가 classpath에서 모든 새 마이그레이션을 적용합니다.

kotlin
// FlywayConfig.kt — Spring Boot에서 Flyway 구성
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.flywaydb.core.Flyway

@Configuration
class FlywayConfig {
    @Bean
    fun flyway(dataSource: DataSource): Flyway {
        return Flyway.configure()
            .dataSource(dataSource)
            .locations("classpath:db/migration")
            .baselineOnMigrate(true)
            .load()
    }
}

Python 프로젝트를 위한 Alembic

Alembic은 SQLAlchemy 위에 구축된 Python용 Schema Migration 도구입니다. 주요 기능은 SQLAlchemy 모델과 현재 데이터베이스 스키마를 비교하여 스크립트를 자동 생성하는 것입니다. Alembic은 Django, FastAPI 그리고 Flask 프로젝트에 적합합니다.

초기화 및 마이그레이션 생성

초기화 (alembic init alembic) 후 접속 문자열을 설정하고, alembic revision --autogenerate 명령어가 SQLAlchemy 모델을 스캔하여 마이그레이션 스크립트를 생성합니다. 개발자는 생성된 코드를 검토한 후 alembic upgrade head로 적용하기만 하면 됩니다. Autogenerate는 수동 DDL 작성의 수시간을 절약할 수 있습니다.

python
# models.py — 자동 생성을 위한 SQLAlchemy 모델
from sqlalchemy import Column, Integer, String, DateTime, Enum
from sqlalchemy.orm import DeclarativeBase
import enum

class OrderStatus(enum.Enum):
    pending = "pending"
    paid = "paid"
    shipped = "shipped"

class Base(DeclarativeBase):
    pass

class Order(Base):
    __tablename__ = "orders"
    id = Column(Integer, primary_key=True)
    status = Column(Enum(OrderStatus), nullable=False)
    created_at = Column(DateTime, nullable=False)

스키마 마이그레이션 최선 실무

경험 있는 팀은 실패 위험을 줄이고 디버깅을 간단하게 만드는 Schema Migration 규칙 집합을 개발했습니다. 이러한 실무를 따르는 것은 성숙된 엔지니어링 문화의 표시입니다. 다섯 가지 주요 규칙은 마이그레이션의 설계, 테스트 그리고 배포를 다막니다.

하나의 마이그레이션 = 하나의 변경

각 Schema Migration은 정확히 하나의 논리적 변경을 해야 합니다: 테이블 생성, 컬럼 추가, 인덱스 수정. 하나의 마이그레이션에 여러 작업을 혼합하면 롤백이 어려워집니다 — 두 번째 작업이 실패하면 첫 번째는 이미 적용되어 별도로 롤백해야 합니다. 작은 단계가 신뢰할 수 있는 마이그레이션의 기반입니다.

게시된 마이그레이션을 수정하지 마세요

마이그레이션이 프로덕션에 적용된 후에는 수정할 수 없습니다 — 문제를 해결하는 새 마이그레이션만 만들 수 있습니다. 게시된 마이그레이션을 수정하면 추적기가 망가집니다: 다른 데이터베이스의 개발자는 해시 일치하지 않음을 볼 것입니다. 불변의 마이그레이션은 모든 환경에서 예측 가능한 동작을 보장합니다.

프로덕션 복사본에서 테스트

Schema Migration을 프로덕션에 적용하기 전에 프로덕션 데이터의 복사본에서 실행하세요. 목적은 실행 속도, 테이블 잠금 여부 그리고 변경의 정확성을 확인하는 것입니다. 클 테이블의 경우 ALTER TABLE이 씨기 동안 쓰기를 차단할 수 있습니다 — 테스트를 통해 사전에 확인할 수 있습니다. 프로덕션 덤프로 Staging은 필수 단계입니다.

새 컬럼에 NOT NULL 피하기

기본값 없이 NOT NULL이 있는 새 컬럼은 마이그레이션 실패의 일반적인 원인입니다. 기존 레코드에서 값이 NULL이 되고 NOT NULL이 오류를 일으킵니다. 최선 실무: 컬럼을 기본값과 nullable로 생성하고, 데이터를 채운 후 별도 마이그레이션에서 NOT NULL을 추가하세요.

자주 묻는 질문

Schema Migration과 Data Migration의 차이는 무엇인가요?

Schema Migration은 데이터베이스 구조(테이블, 컬럼, 인덱스)를 관리하고, Data Migration은 내용(행, 문서)을 관리합니다. Schema Migration이 항상 먼저 실행되어 대상 스키마를 만들고 그 다음에 Data Migration이 데이터를 채욹니다. 다른 도구: 스키마에는 Flyway, 데이터에는 ETL입니다.

새 프로젝트에 어떤 스키마 마이그레이션 도구를 선택해야 하나요?

Java/Kotlin의 경우 — Flyway가 가장 간단하고 빠릅니다. Python의 경우 — Alembic이 SQLAlchemy와 연동되어 있습니다. .NET의 경우 — Entity Framework Migrations입니다. 다중 언어 프로젝트의 경우 — Liquibase를 형식 없이 사용할 수 있습니다.

Schema Migration을 어떻게 롤백하나요?

Flyway는 자동 롤백을 지원하지 않습니다 — 별도의 복구 스크립트가 필요합니다. Liquibase는 XML/YAML 형식에 대해 자동으로 롤백을 생성합니다. Alembic은 각 마이그레이션에 downgrade 함수를 만듭니다. 롤백 대신 새 마이그레이션을 만드는 불변 접근법이 현대적이며 더 나은 방법입니다.

프로덕션에서 마이그레이션이 실패하면 어떻게 됩나요?

도구가 마이그레이션을 실패로 표시합니다. 데이터베이스는 적용 전 상태로 유지됩니다(자동 커미가 없었다면). 새 마이그레이션에서 오류를 수정하고 다시 실행해야 합니다. 절대로 실패한 마이그레이션을 수정하지 마세요 — 새 것을 만드세요.

스키마 마이그레이션 도구를 사용하는 것이 의무인가요?

프로덕션 프로젝트에는 — 그렧습니다. Git 외부의 수동 DDL 변경은 스키마 평차, 망가진 배포, 데이터 손실을 초래합니다. MVP에서도 최소 도구를 사용하세요 — 예를 들어 몇 개의 SQL 스크립트를 가진 Flyway입니다. 가장 처음 staging에 배포할 때 효과를 볼 것입니다.

요약

  • Schema Migration — Git의 스크립트를 통한 데이터베이스 구조의 버전 변경.
  • dev, staging, 프로덕션 환경 간 스키마 일관성 문제를 해결합니다.
  • Flyway는 Java/Kotlin 표준, Alembic은 Python, Liquibase는 다중 언어 프로젝트용입니다.
  • 하나의 마이그레이션 = 하나의 변경. 게시된 마이그레이션을 수정하지 마세요.
  • 적용 전에 프로덕션 데이터 복사본에서 마이그레이션을 테스트하세요.
  • 새 컬럼은 기본값과 nullable로 생성하고, 별도 마이그레이션에서 NOT NULL을 추가하세요.
  • 고위 마이그레이션의 자동 롤백보다 새 마이그레이션을 통한 불변 접근법이 더 신뢰합니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기