배경
Polaris 백엔드는 여러 도메인 모듈로 구성되어 있고, 각 도메인은 자기 책임에 맞는 DB 테이블을 가진다. MVP 개발 중에도 사용자, 캐릭터, 미션, 아이템, 별조각, 공유, 출석 등 여러 영역에서 스키마 변경이 계속 발생할 수 있다.
스키마 변경을 수동으로 관리하면 다음 문제가 생긴다.
- 팀원마다 로컬 DB 상태가 달라질 수 있다.
- 어떤 테이블이나 컬럼이 언제 추가되었는지 추적하기 어렵다.
- 배포 환경에서 애플리케이션 코드와 DB schema가 맞지 않을 수 있다.
- PR 리뷰에서 DB 변경 내용을 확인하기 어렵다.
- 테스트 환경을 새로 만들 때 초기 schema를 재현하기 어렵다.
따라서 DB schema 변경을 코드와 함께 버전 관리할 방법이 필요했다.
논의한 문제
팀에서는 다음 질문을 기준으로 migration 도구를 검토했다.
- DB 변경 이력을 Git으로 관리할 수 있는가?
- 로컬 개발 환경에서 자동으로 schema를 맞출 수 있는가?
- 운영 배포 시 schema 불일치를 조기에 발견할 수 있는가?
- SQL을 직접 확인하고 리뷰할 수 있는가?
- Spring Boot와 쉽게 통합되는가?
- 여러 도메인 모듈에서 일관된 규칙으로 사용할 수 있는가?
검토한 선택지
선택지 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 |