Flyway 사용법 (#1)
지금까진 ERDCloud로 전체적인 DB 구조와 컬럼을 관리하고, 변경사항이 생기면 세 가지 단계를 거쳤습니다. 먼저 ERDCloud를 수정하고, 그다음 Spring Boot 코드(Entity)를 수정한 뒤, 마지막으로 DB에 직접 쿼리를 실행해 반영하는 방식이었습니다.
하지만 이 과정에는 몇 가지 문제가 있었습니다. 가장 큰 문제는 DB에 직접 쿼리를 날리는 시점과 실제 서비스 배포 시점이 정확히 맞아야 한다는 점이었습니다. 시점이 어긋나면 서비스가 정상적으로 동작하지 않을 위험이 있었습니다. 또한, Entity와 ERDCloud 간 불일치 문제가 자주 발생했습니다. 원래는 ERDCloud에서 DDL을 추출한 뒤, 그중에서 수정되거나 추가된 부분만 직접 쿼리로 DB에 적용하는 방식을 썼는데, 테이블 수가 많아지고 변경사항이 누적되다 보니, Entity와 ERDCloud 간 동기화가 맞지 않으면 언제든 예기치 못한 문제가 생길 수 있었습니다.
이런 상황에서 최소한 Entity와 실제 DB 테이블 간에는 불일치가 없어야 한다는 점이 중요했고, 동시에 배포 타이밍에 맞춰 직접 쿼리를 적용해야 하는 리스크를 줄일 필요가 있었습니다. 따라서 이러한 문제들을 해결하기 위해Flyway를 도입하게 되었습니다.
1. Spring Boot 적용 방법
실행환경: gradle, springboot 3.5.6
1.1 의존성 추가
먼저 프로젝트에 Flyway를 적용하기 위해 빌드 도구에 의존성을 추가해야 합니다.
build.gradle 파일에 flyway-mysql 의존성을 추가합니다.
//flyway
implementation 'org.flywaydb:flyway-mysql'
1.2 설정 (application.yml)
그다음 application.yml 혹은 application.properties 파일에서 데이터베이스 연결 정보와 함께 Flyway 설정을 추가합니다.
spring:
flyway:
enabled: true # flyway 활성화
baseline-on-migrate: true # DB가 비어있지 않아도 baseline 잡고 시작
locations: classpath:db # migration 파일 위치
enabled: true → 실행 시점에 자동으로 DB 마이그레이션 반영 됩니다.
locations → 기본값이 classpath:db/migration이라 커스텀 경로를 사용하지 않는 이상 따로 설정하지 않아도 됩니다.
baseline-on-migrate: true → 기존 DB가 이미 초기화되어 있더라도, Flyway가 그 상태를 baseline으로 잡고 이후 스크립트부터 적용 해줍니다. 만약 해당 설정값이 false 라면 이미 테이블이 있을때 Flyway는 "스키마가 손상된 상태"라고 판단하고 오류 발생시킵니다. 즉, 기존 DB → Flyway 도입이 불가능해 집니다.
1.3 마이그레이션 스크립트 작성 규칙
마이그레이션 스크립트는 정해진 규칙에 맞춰 파일명을 작성해야 합니다.
일반적으로 V숫자__설명.sql 형태를 사용합니다.
예를 들어, 초기 스키마를 정의할 때는 V1__init.sql, 이후 사용자 테이블을 추가한다면 V2__add_user_table.sql 같은 식입니다.
작성한 스크립트 파일은 src/main/resources/db/migration 디렉터리에 두면, 애플리케이션이 실행될 때 자동으로 해당 SQL들이 순서대로 실행되어 DB에 반영됩니다.
1.4 실제 구현 예시

v1__init.sql
CREATE TABLE `member`
(
`id` BIGINT NOT NULL AUTO_INCREMENT,
`nickname` VARCHAR(100) NOT NULL,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
);
application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test
username: root
password: 1234
flyway:
enabled: true # flyway 활성화
baseline-on-migrate: true # DB가 비어있지 않아도 baseline 잡고 시작
locations: classpath:db # migration 파일 위치
우리의 예상대로라면, 위, 설정들에 의하여 Spring 실행시 db 에 member 테이블이 생겨야 합니다.

서버를 실행하면 Flyway가 db/migration에 있는 마이그레이션 스크립트를 읽어서 순서대로 실행합니다. 그 결과 DB에는 우리가 작성한 member 테이블이 생성되고, 동시에 Flyway가 자체적으로 관리하는 flyway_schema_history 테이블도 추가됩니다.
flyway_schema_history는 DB 마이그레이션 이력이 저장되는 버전 관리 테이블이고, 이를 통해 Flyway는 중복 실행을 방지하면서 다음 버전부터 이어서 실행할 수 있게 됩니다.
2. 문제점
해당 방법을 사용한다면, 제가 가장 큰 문제라 생각했던, "DB에 직접 쿼리를 날리는 시점과 실제 서비스 배포 시점이 정확히 맞아야 한다는 점 " 해당 문제점이 해결됩니다.
다만, flyway 를 사용하다보니 다음과 같은 2가지 문제점이 존재했습니다.
- db/migration 안에 있는 sql 파일이 우리의 entity 와 완벽히 일치한다는 보장이 있는가?
- db/migration 안에 있는 sql 파일이 무한정 늘어나면 관리는 어떻게 할것인가?
다음글은 해당 문제를 어떻게 해결했는지에 대해 작성해보겠습니다.
'Framework > Spring' 카테고리의 다른 글
| Flyway 사용법 (#2) (1) | 2025.11.15 |
|---|---|
| Spring WebSocket(STOMP) 통합 테스트 정리 (0) | 2025.10.17 |
| JPQL 실행 시 Flush와 영속성 컨텍스트 동작 확인 (0) | 2024.07.22 |
| API 통신 시 null 값 처리: 포함 vs. 미포함의 장단점 (0) | 2024.07.22 |
| JPA에서 단방향 및 양방향 일대일 관계의 외래키 처리와 지연 로딩 문제 (1) | 2024.07.22 |