최종프로젝트에서 flyway 쓰는 이유

2026. 5. 21. 23:49·IL/TIL

배경

Polaris 백엔드는 여러 도메인 모듈로 구성되어 있고, 각 도메인은 자기 책임에 맞는 DB 테이블을 가진다. MVP 개발 중에도 사용자, 캐릭터, 미션, 아이템, 별조각, 공유, 출석 등 여러 영역에서 스키마 변경이 계속 발생할 수 있다.

스키마 변경을 수동으로 관리하면 다음 문제가 생긴다.

  • 팀원마다 로컬 DB 상태가 달라질 수 있다.
  • 어떤 테이블이나 컬럼이 언제 추가되었는지 추적하기 어렵다.
  • 배포 환경에서 애플리케이션 코드와 DB schema가 맞지 않을 수 있다.
  • PR 리뷰에서 DB 변경 내용을 확인하기 어렵다.
  • 테스트 환경을 새로 만들 때 초기 schema를 재현하기 어렵다.

따라서 DB schema 변경을 코드와 함께 버전 관리할 방법이 필요했다.

논의한 문제

팀에서는 다음 질문을 기준으로 migration 도구를 검토했다.

  1. DB 변경 이력을 Git으로 관리할 수 있는가?
  2. 로컬 개발 환경에서 자동으로 schema를 맞출 수 있는가?
  3. 운영 배포 시 schema 불일치를 조기에 발견할 수 있는가?
  4. SQL을 직접 확인하고 리뷰할 수 있는가?
  5. Spring Boot와 쉽게 통합되는가?
  6. 여러 도메인 모듈에서 일관된 규칙으로 사용할 수 있는가?

검토한 선택지

선택지 1. 수동 SQL 관리

개발자가 DB에 직접 SQL을 실행하거나, 별도 문서에 SQL을 적어두고 필요할 때 적용하는 방식이다.

장점:

  • 별도 도구 설정이 필요 없다.
  • 초기 실험 단계에서는 빠르게 작업할 수 있다.
  • 작은 변경은 바로 DB에 반영할 수 있다.

단점:

  • 누가 어떤 SQL을 언제 실행했는지 추적하기 어렵다.
  • 팀원별 로컬 DB 상태가 달라질 가능성이 높다.
  • PR에서 스키마 변경을 리뷰하기 어렵다.
  • 운영 환경 반영 누락 위험이 있다.
  • 신규 개발자가 환경을 구성할 때 같은 DB 상태를 재현하기 어렵다.

검토 결과:

MVP라도 여러 도메인과 보상/거래 정합성이 있으므로 수동 SQL 관리는 위험하다고 판단했다.

선택지 2. Hibernate ddl-auto

JPA Entity를 기준으로 Hibernate가 schema를 자동 생성하거나 업데이트하게 하는 방식이다.

장점:

  • 초기 개발 속도가 빠르다.
  • Entity 변경을 DB에 빠르게 반영할 수 있다.
  • 별도 SQL 작성량이 줄어든다.

단점:

  • 실제 적용되는 DDL을 명확히 리뷰하기 어렵다.
  • 운영 환경에서 안전하게 사용하기 어렵다.
  • index, unique, check constraint, partial index 등 세밀한 제약을 관리하기 어렵다.
  • Entity 변경과 DB 변경 이력이 명시적으로 남지 않는다.
  • 의도하지 않은 schema 변경이 발생할 수 있다.

검토 결과:

Polaris는 미션 완료 보상, 별조각 원장, 아이템 구매처럼 DB 제약이 중요한 영역이 많다. 따라서 schema를 자동 생성에 맡기는 방식은 적합하지 않다고 판단했다. ddl-auto는 운영 기준으로 none 또는 validate 방향이 적절하다.

선택지 3. Flyway

SQL migration 파일을 버전 순서대로 적용하는 방식이다. Spring Boot 실행 시 migration을 검증하고 적용할 수 있다.

장점:

  • SQL 변경 이력을 Git으로 관리할 수 있다.
  • PR에서 schema 변경을 직접 리뷰할 수 있다.
  • 로컬, 테스트, 운영 환경의 schema 차이를 줄일 수 있다.
  • Spring Boot와 통합이 쉽다.
  • 적용된 migration 이력이 DB에 남는다.
  • 실패 시 애플리케이션 기동 단계에서 문제를 빠르게 발견할 수 있다.

단점:

  • migration 파일명 규칙을 지켜야 한다.
  • 이미 적용된 migration을 수정하면 checksum 문제가 발생한다.
  • Entity 변경과 migration 작성이 함께 필요하다.
  • 초기 개발자가 migration 규칙에 익숙해져야 한다.

검토 결과:

Polaris처럼 팀원이 병렬로 개발하고, DB 정합성이 중요한 서비스에는 Flyway가 가장 적합하다고 판단했다. SQL을 직접 관리하므로 제약 조건과 index를 명확히 표현할 수 있고, 변경 이력을 PR 단위로 추적할 수 있다.

결정

Polaris 백엔드는 DB migration 도구로 Flyway를 사용한다.

각 도메인 모듈은 다음 경로에 migration 파일을 둔다.

{module}/src/main/resources/db/migration

예시:

mission/src/main/resources/db/migration/V1__init_mission_schema.sql
character/src/main/resources/db/migration/V1__init_character_schema.sql
item/src/main/resources/db/migration/V1__init_item_schema.sql

결정 이유

1. DB 변경 이력을 코드와 함께 관리할 수 있다

Flyway migration 파일은 Git에 포함된다. 따라서 PR에서 애플리케이션 코드 변경과 DB schema 변경을 함께 확인할 수 있다.

예를 들어 미션 완료 기능을 추가하는 PR에서는 다음 변경을 함께 리뷰할 수 있다.

  • user_missions 테이블 추가
  • mission_completion_answers 테이블 추가
  • idempotency key unique constraint 추가
  • 관련 Entity와 Repository 추가
  • 상태 전이 application service 추가

2. 환경 간 schema 불일치를 줄일 수 있다

개발자 로컬 DB, 테스트 DB, 배포 DB가 서로 다른 schema를 가지면 오류가 늦게 발견된다. Flyway는 애플리케이션 시작 시 migration 상태를 확인하므로 schema 불일치를 빠르게 발견할 수 있다.

3. 정합성 제약을 명확히 표현할 수 있다

Polaris는 DB 제약이 중요하다. 예를 들어 다음과 같은 제약은 SQL migration에 명시되어야 한다.

  • 하루 미션 stack 순서 중복 방지
  • 미션 완료 보상 중복 지급 방지
  • 아이템 중복 보유 방지
  • 출석 중복 지급 방지
  • 공유 보상 중복 지급 방지

Flyway는 이러한 제약 조건을 명시적인 SQL로 남길 수 있다.

4. Spring Boot와 통합이 쉽다

현재 각 도메인 모듈은 Spring Boot 애플리케이션이다. Flyway는 Spring Boot auto configuration과 잘 통합되며, 애플리케이션 시작 시 migration을 자동으로 적용할 수 있다.

migration 작성 규칙

파일명

Flyway migration 파일명은 다음 형식을 따른다.

V{version}__{description}.sql

예시:

V1__init_mission_schema.sql
V2__add_mission_interactions.sql
V3__add_mission_reward_idempotency.sql

주의:

v1__.sql처럼 소문자 v를 사용하거나 description이 없는 파일명은 사용하지 않는다. Flyway가 migration으로 인식하지 못하거나 naming warning을 발생시킬 수 있다.

이미 적용된 migration 수정 금지

한 번 DB에 적용된 migration 파일은 수정하지 않는다. 변경이 필요하면 새 version의 migration을 추가한다.

나쁜 예:

V1__init_mission_schema.sql 수정

좋은 예:

V2__alter_user_missions_add_idempotency_key.sql 추가

Entity와 migration 동시 관리

Entity만 만들고 migration을 누락하지 않는다. migration만 만들고 Entity를 누락하지 않는다.

PR에는 다음이 함께 포함되어야 한다.

  • migration SQL
  • Entity
  • Repository
  • application service
  • 테스트

constraint와 index 명시

정합성 또는 조회 성능에 중요한 constraint와 index는 migration에 명시한다.

미션 도메인 예시:

unique (user_id, mission_date, stack_order)
unique (idempotency_key)
index (user_id, mission_date, status)
index (user_id, created_at)

ddl-auto 정책

JPA의 ddl-auto는 schema 자동 생성을 목적으로 사용하지 않는다.

권장:

spring:
  jpa:
    hibernate:
      ddl-auto: none

테스트나 로컬 실험에서 예외적으로 다른 값을 사용하더라도, 팀 기준 schema 관리는 Flyway가 담당한다.

결과

  • DB schema 변경은 Flyway migration으로 관리한다.
  • migration 파일은 각 도메인 모듈의 db/migration 아래에 둔다.
  • schema 변경은 PR 리뷰 대상에 포함한다.
  • migration naming convention을 지킨다.
  • 이미 적용된 migration은 수정하지 않는다.
  • 애플리케이션 시작 시 Flyway validation 실패가 발생하면 schema 불일치로 보고 수정한다.

후속 과제

  • 각 도메인별 기존 migration 파일명을 점검한다.
  • v1__.sql처럼 Flyway가 인식하지 못하는 파일을 정리한다.
  • ERD와 실제 migration의 테이블/컬럼/제약 조건을 비교한다.
  • PR template에 migration 확인 항목을 추가한다.
저작자표시 비영리 (새창열림)

'IL > TIL' 카테고리의 다른 글

CloudFront 기반 이미지 에셋 관리 방식 채택  (0) 2026.05.26
20260522 [TIL] - 채팅 문의 인덱싱 정리  (0) 2026.05.22
외부 AI Provider 호출 보호를 위한 Redis 기반 Rate Limit 적용  (0) 2026.05.20
20260510 [TIL] - 카페 주문 시스템  (0) 2026.05.10
20260404 [TIL] - 플러스 스프링 과제  (0) 2026.04.02
'IL/TIL' 카테고리의 다른 글
  • CloudFront 기반 이미지 에셋 관리 방식 채택
  • 20260522 [TIL] - 채팅 문의 인덱싱 정리
  • 외부 AI Provider 호출 보호를 위한 Redis 기반 Rate Limit 적용
  • 20260510 [TIL] - 카페 주문 시스템
견지
견지
개발로 개발하는지 새발로 개발하는지 내가 개인 건지 새인 건지 사람인 건지
  • 견지
    개발새발
    견지
  • 전체
    오늘
    어제
    • 분류 전체보기 (33)
      • ... (0)
      • IL (33)
        • TIL (29)
        • WIL (4)
        • MIL (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    git
    JSP
    JavaScript
    DB
    HTML
    java
    oracle
    CSS
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
견지
최종프로젝트에서 flyway 쓰는 이유
상단으로

티스토리툴바