Flyway 도입 가이드: 이미 돌아가는 DB에 버전 관리를 얹는 법
애플리케이션 코드는 git으로 관리하면서 DB 스키마는 아직도 누군가 콘솔에서 ALTER TABLE을 칩니다. Flyway는 그 SQL을 파일로 만들고, 순서대로 한 번씩만 실행하고, 무엇을 실행했는지 DB 안에 적어 둡니다. 빈 DB가 아니라 이미 운영 중인 DB에 도입하는 경우까지 다룹니다.
DB 스키마도 코드입니다
새 기능을 만들면서 컬럼 하나를 추가한다고 해 봅시다. 로컬 DB에서 ALTER TABLE users ADD COLUMN phone VARCHAR(20)을 실행하고, 코드를 짜고, PR을 올립니다. 리뷰가 끝나고 배포합니다. 그리고 운영 서버가 Unknown column 'phone'으로 죽습니다.
누군가 스테이징과 운영 DB에도 같은 SQL을 쳐야 했는데, 그 사실이 코드 어디에도 적혀 있지 않았기 때문입니다. 이 문제는 팀이 커질수록 다음 형태로 나타납니다.
- 환경마다 스키마가 다릅니다. 로컬, 개발, 스테이징, 운영이 조금씩 어긋나고, 어디가 어떻게 다른지 아무도 모릅니다.
- 신규 입사자가 DB를 못 만듭니다. 최신 스키마를 만들려면 선배에게 덤프 파일을 받아야 합니다. 그 덤프가 언제 것인지는 아무도 모릅니다.
- 배포 순서가 사람 머릿속에 있습니다. "이번 배포는 SQL 먼저 치고 앱 올리세요"가 슬랙 메시지로 전달됩니다. 새벽 배포에서 이 메시지는 잊힙니다.
코드에는 이런 문제가 없습니다. git이 변경 이력을 순서대로 갖고 있고, 어떤 커밋이 배포되었는지 알 수 있고, 새 사람은 clone 한 번으로 최신 상태를 받습니다. Flyway는 이것을 DB 스키마에 그대로 적용하는 도구입니다.
ddl-auto: update는 답이 아닙니다
Spring Boot를 쓴다면 spring.jpa.hibernate.ddl-auto: update가 떠오를 수 있습니다. 엔티티 클래스를 고치면 Hibernate가 알아서 테이블을 바꿔 주니 편합니다. 하지만 운영 환경에서는 쓰면 안 됩니다.
- 컬럼을 추가할 뿐, 이름을 바꾸거나 지우는 변경은 반영하지 않습니다. 스키마에 쓰레기가 쌓입니다.
- 어떤 DDL이 실행될지 배포 전에 알 수 없습니다. 리뷰할 대상이 없습니다.
- 인덱스, 제약 조건, 데이터 이관 같은 실제로 중요한 변경을 표현할 수 없습니다.
Flyway를 도입하면 이 값은 validate로 바뀝니다. Hibernate는 스키마를 고치는 대신, 엔티티와 실제 테이블이 맞는지만 검사하고 어긋나면 애플리케이션을 띄우지 않습니다. 스키마를 바꾸는 권한은 Flyway 한 곳으로 모입니다.
Flyway가 하는 일
Flyway는 Redgate가 관리하는 DB 마이그레이션 도구입니다. 하는 일은 한 문장으로 요약됩니다.
버전이 붙은 SQL 파일을 버전 순서대로 한 번씩만 실행하고, 무엇을 실행했는지 DB 안의 테이블에 기록합니다.
핵심은 마지막 절반입니다. 기록이 DB 안에 있기 때문에, Flyway는 어떤 환경에 붙어도 "이 DB는 지금 몇 번까지 적용되었는가"를 스스로 알아냅니다. 사람의 기억이나 슬랙 메시지가 필요 없습니다.
db/migration/ 운영 DB
├── V1__create_users.sql ┌──────────────────────┐
├── V2__add_phone.sql ───► │ 지금 V2까지 적용됨 │
├── V3__create_orders.sql │ → V3, V4만 실행하면 │
└── V4__add_index.sql │ 된다 │
└──────────────────────┘
flyway_schema_history 테이블
그 기록이 저장되는 곳이 flyway_schema_history 테이블입니다. Flyway가 처음 실행될 때 스스로 만듭니다. 컬럼은 다음과 같습니다.
| 컬럼 | 의미 |
|---|---|
installed_rank | 적용된 순서. 1부터 증가합니다. |
version | 마이그레이션 버전. 반복 실행 마이그레이션은 NULL입니다. |
description | 파일 이름에서 뽑아낸 설명. |
type | SQL, JDBC, BASELINE 등. |
script | 실제 파일 이름. |
checksum | 파일 내용의 체크섬. 파일이 바뀌었는지 판별하는 근거입니다. |
installed_by | 실행한 DB 계정. |
installed_on | 실행 시각. |
execution_time | 실행에 걸린 시간(ms). 느린 마이그레이션을 찾을 때 씁니다. |
success | 성공 여부. |
운영 중 문제가 생기면 이 테이블부터 봅니다. 평범한 테이블이라 그냥 조회하면 됩니다.
SELECT installed_rank, version, description,
success, execution_time, installed_on
FROM flyway_schema_history
ORDER BY installed_rank DESC
LIMIT 10;
마이그레이션 파일 규칙
Flyway는 파일 이름으로 모든 것을 판단합니다. 규칙은 접두사 + 버전 + 구분자 + 설명 + 확장자입니다.
V2__add_phone_to_users.sql │ │ │ └── 확장자 (.sql) │ │ └── 설명 (밑줄은 공백으로 표시됨) │ └── 구분자 (밑줄 두 개, __) └── 접두사 + 버전
접두사는 세 종류입니다.
| 접두사 | 이름 | 언제 실행되나 | 예시 |
|---|---|---|---|
V | Versioned | 버전 순서대로 딱 한 번 | V3__create_orders.sql |
R | Repeatable | 내용이 바뀔 때마다, 버전 마이그레이션 이후에 | R__user_summary_view.sql |
U | Undo | 같은 버전을 되돌릴 때 (Enterprise 전용) | U3__create_orders.sql |
실무에서 V와 R만 씁니다. U는 유료 에디션 기능인데, 뒤에서 설명하겠지만 유료라서 안 쓰는 것이 아니라 애초에 롤백 전략으로 권하기 어렵습니다.
Repeatable은 언제 쓰나
R은 몇 번을 실행해도 결과가 같은 것에만 씁니다. 뷰, 저장 프로시저, 함수 같은 것들입니다. 이런 대상은 CREATE OR REPLACE로 다시 만들면 그만이라, 변경할 때마다 새 버전 파일을 만들 필요가 없습니다. 파일 하나를 계속 고치면 되고 git diff에 변경 내역이 그대로 남습니다.
CREATE OR REPLACE VIEW active_user_view AS SELECT u.id, u.email, u.phone, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE u.deleted_at IS NULL GROUP BY u.id, u.email, u.phone;
반대로 ALTER TABLE이나 INSERT는 절대 R에 넣으면 안 됩니다. 두 번 실행되면 깨지거나 데이터가 중복됩니다.
버전 번호는 어떻게 매기나
두 가지 방식이 있고, 팀 규모가 갈림길입니다.
- 순차 번호(
V1,V2,V3): 읽기 쉽고 순서가 명확합니다. 대신 두 사람이 동시에V5를 만들면 merge 시점에 충돌합니다. - 타임스탬프(
V20260903_1430): 충돌이 사실상 없습니다. 대신 파일 이름이 길고 순서를 눈으로 훑기 어렵습니다.
사람이 서너 명이면 순차 번호로 시작해도 충분합니다. 충돌이 실제로 귀찮아지는 시점에 타임스탬프로 바꾸면 됩니다. 이미 적용된 파일은 그대로 두고 새 파일부터 새 규칙을 쓰면 되므로, 나중에 바꿔도 비용이 크지 않습니다.
Spring Boot에 붙이기
의존성 두 줄과 설정 몇 줄이면 됩니다. Flyway 10부터 DB별 지원이 별도 모듈로 분리되었으므로, flyway-core만 넣으면 PostgreSQL이나 MySQL에서 동작하지 않습니다. 여기서 막히는 사람이 많습니다.
dependencies {
implementation("org.flywaydb:flyway-core")
// PostgreSQL을 쓴다면
implementation("org.flywaydb:flyway-database-postgresql")
// MySQL / MariaDB를 쓴다면
// implementation("org.flywaydb:flyway-mysql")
}
Spring Boot의 의존성 관리가 버전을 맞춰 주므로 버전은 적지 않습니다. Maven이라면 같은 두 아티팩트를 <dependency>로 추가하면 됩니다.
spring:
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: false
validate-on-migrate: true
out-of-order: false
jpa:
hibernate:
ddl-auto: validate
각 값의 의미는 다음과 같습니다.
locations: 마이그레이션 파일을 찾을 경로입니다. 기본값이classpath:db/migration이라 사실 생략해도 됩니다. 다만 이 값을 지정하면 기본값을 덮어씁니다. 테스트용 경로를 추가하려면classpath:db/migration도 같이 적어야 합니다.validate-on-migrate: 실행 전에 적용된 마이그레이션과 현재 파일이 일치하는지 검사합니다. 기본값이true이고, 끄지 마세요. 이것이 꺼져 있으면 파일이 몰래 바뀐 것을 알 방법이 없습니다.out-of-order:V5가 이미 적용된 DB에 뒤늦게V4가 들어왔을 때 실행할지 여부입니다. 기본값false를 유지하세요. 순서를 건너뛴 스키마는 환경마다 결과가 달라집니다.
디렉토리는 이렇게 만듭니다.
src/main/resources/
└── db/
└── migration/
├── V1__create_users.sql
├── V2__add_phone_to_users.sql
├── V3__create_orders.sql
└── R__active_user_view.sql
이제 애플리케이션을 띄우면 Flyway가 시작 시점에 자동으로 실행됩니다. 로그에 적용된 마이그레이션이 찍힙니다.
Flyway Community Edition 13.4.0 by Redgate Database: jdbc:postgresql://localhost:5432/app (PostgreSQL 16.4) Successfully validated 4 migrations (execution time 00:00.031s) Creating Schema History table "public"."flyway_schema_history" ... Migrating schema "public" to version "1 - create users" Migrating schema "public" to version "2 - add phone to users" Migrating schema "public" to version "3 - create orders" Successfully applied 3 migrations (execution time 00:00.194s)
이미 운영 중인 DB에 도입하기
여기가 실제로 어려운 부분입니다. 지금까지의 설명은 빈 DB를 전제로 했습니다. 하지만 여러분이 Flyway를 도입하려는 이유는 이미 몇 년째 돌아가는 DB가 있고, 그 스키마를 아무도 통제하지 못하기 때문일 것입니다.
이 DB에 그냥 Flyway를 붙이면 V1__create_users.sql이 실행되면서 table already exists로 실패합니다. 필요한 것은 baseline입니다. "여기까지는 이미 되어 있는 것으로 친다"는 선언입니다.
1단계. 현재 스키마를 파일로 뽑는다
운영 DB의 현재 스키마를 데이터 없이 덤프합니다.
# PostgreSQL pg_dump --schema-only --no-owner --no-privileges \ -h prod-db -U app_user app_db > baseline.sql # MySQL mysqldump --no-data --skip-add-drop-table \ -h prod-db -u app_user -p app_db > baseline.sql
덤프 파일을 열어 정리합니다. SET 구문, 소유자 지정, 주석 등 재현에 필요 없는 것들을 지웁니다. 그리고 이 파일을 V1__baseline.sql이라는 이름으로 db/migration에 넣습니다.
2단계. 빈 DB에서 검증한다
이 파일이 정말로 운영과 같은 스키마를 만드는지 확인해야 합니다. 로컬의 빈 DB에 V1__baseline.sql만으로 스키마를 만들고, 애플리케이션을 ddl-auto: validate로 띄웁니다. 뜬다면 엔티티 기준으로는 일치한다는 뜻입니다.
더 확실하게 하려면 두 스키마를 덤프해서 diff로 비교합니다.
pg_dump --schema-only --no-owner -h localhost app_db \ | grep -v '^--' > local.sql diff local.sql baseline.sql
3단계. 운영 DB에 baseline을 찍는다
이제 운영 DB에 "V1은 이미 적용된 것으로 간주하라"고 알려 줍니다. 두 가지 방법이 있습니다.
spring:
flyway:
baseline-on-migrate: true
baseline-version: 1
baseline-description: "existing schema"
baseline-on-migrate: true는 flyway_schema_history 테이블이 없을 때만 동작합니다. 테이블이 없으면 테이블을 만들고, baseline-version까지를 적용된 것으로 기록한 뒤, 그 다음 버전부터 실행합니다.
CLI를 쓴다면 명시적으로 한 번만 실행하는 쪽이 더 안전합니다.
flyway -baselineVersion="1" \
-baselineDescription="existing schema" \
baseline
4단계. 확인한다
flyway info는 상태를 표로 보여 줍니다. 도입 직후에는 이런 모습이어야 합니다.
+-----------+---------+-----------------+----------+------------+----------+ | Category | Version | Description | Type | Installed | State | +-----------+---------+-----------------+----------+------------+----------+ | | 1 | existing schema | BASELINE | 2026-09-03 | Baseline | | Versioned | 2 | add phone | SQL | | Pending | | Versioned | 3 | create orders | SQL | | Pending | +-----------+---------+-----------------+----------+------------+----------+
V1이 Baseline이고 그 뒤가 Pending이면 성공입니다. V1이 Pending으로 남아 있다면 baseline이 안 찍힌 것이니, 그 상태로 배포하면 안 됩니다.
팀에서 지킬 규칙 네 가지
도구를 붙이는 것보다 규칙을 합의하는 쪽이 어렵습니다. 최소한 이 네 가지는 도입 시점에 정해 두세요.
1. 적용된 마이그레이션 파일은 절대 수정하지 않는다
Flyway는 파일 내용의 체크섬을 flyway_schema_history에 저장합니다. 이미 적용된 파일을 고치면 다음 실행에서 검증에 걸립니다.
Migration checksum mismatch for migration version 3 -> Applied to database : 1284725619 -> Resolved locally : -905442731 Either revert the changes to the migration, or run repair to update the schema history.
이것은 버그가 아니라 Flyway가 제대로 일하고 있다는 신호입니다. "내 로컬에서는 아직 안 돌았으니까 그냥 고쳐도 되겠지"가 사고의 시작입니다. 여러분의 로컬에서는 안 돌았어도 동료의 로컬과 개발 서버에서는 이미 돌았습니다. 오타 하나를 고치더라도 새 파일을 만드세요.
예외는 딱 하나, 아직 어디에도 배포되지 않은 브랜치 안의 파일입니다. 이때는 로컬 DB를 지우고 다시 만들면 됩니다.
2. 롤백은 undo가 아니라 다음 마이그레이션으로 한다
Flyway의 U 접두사 undo 마이그레이션은 Enterprise 에디션 기능입니다. 하지만 유료가 아니더라도 실무에서 권하기 어렵습니다. DROP COLUMN을 되돌리는 undo 스크립트는 컬럼을 다시 만들 수는 있어도 거기 있던 데이터를 되살릴 수는 없기 때문입니다.
현실적인 전략은 앞으로 고치는 것입니다. V7이 잘못됐다면 V7을 되돌리는 대신 V8__fix_v7.sql을 만듭니다. 그리고 애초에 되돌릴 일이 없도록, 파괴적인 변경은 여러 배포에 나눠서 합니다.
컬럼 이름을 바꾸고 싶을 때 (한 번에 하면 배포 중 장애) 배포 1: 새 컬럼 추가 V10__add_new_column.sql 배포 2: 양쪽에 모두 쓰는 코드 (앱 배포만) 배포 3: 데이터 복사 V11__backfill_new_column.sql 배포 4: 새 컬럼만 읽는 코드 (앱 배포만) 배포 5: 옛 컬럼 삭제 V12__drop_old_column.sql
귀찮아 보이지만, 각 단계에서 앱의 옛 버전과 새 버전이 동시에 떠 있어도 안전합니다. 무중단 배포를 한다면 이 순서가 필수입니다.
3. 버전 충돌은 merge 전에 해결한다
두 브랜치가 각각 V8을 만들었다면, 나중에 merge하는 쪽이 자기 파일을 V9로 이름을 바꿉니다. git은 파일 이름이 다르므로 충돌을 알려 주지 않습니다. 사람이 봐야 합니다.
PR 체크리스트에 "새 마이그레이션 파일의 버전이 main과 겹치지 않는가"를 넣거나, CI에서 중복 버전을 검사하는 스크립트를 한 줄 돌리세요.
ls src/main/resources/db/migration/V*.sql \ | sed 's#.*/V\([0-9]*\)__.*#\1#' | sort | uniq -d
출력이 있으면 중복된 버전이 있다는 뜻이니 CI를 실패시킵니다.
4. 마이그레이션도 코드 리뷰 대상이다
SQL 파일은 리뷰에서 자주 그냥 넘어갑니다. 하지만 앱 코드는 버그가 나면 롤백하면 되고, 마이그레이션은 롤백이 안 됩니다. 리뷰에서 최소한 이 세 가지는 봅니다.
- 이
ALTER TABLE이 테이블을 잠그는가. 몇 만 행이면 순식간이지만, 수천만 행이면 몇 분에서 몇 시간 동안 쓰기가 막힙니다. - 지우는 것이 있는가.
DROP과NOT NULL추가는 되돌릴 수 없습니다. INSERT에 컬럼 이름이 명시되어 있는가.INSERT INTO t VALUES (...)는 나중에 컬럼이 추가되면 깨집니다.
알아 둘 명령어
Spring Boot에 붙이면 대부분 자동으로 돌지만, 문제가 생겼을 때는 CLI나 Gradle 플러그인으로 직접 쓰게 됩니다.
| 명령어 | 하는 일 | 언제 쓰나 |
|---|---|---|
info | 각 마이그레이션의 상태를 표로 출력 | 가장 먼저 치는 명령어. 상태 파악 |
migrate | 대기 중인 마이그레이션 실행 | 배포. 보통 앱 시작 시 자동 |
validate | 파일과 기록이 일치하는지 검사 | CI에서 배포 전 검증 |
baseline | 기존 DB에 시작점 기록 | 도입 시점에 한 번 |
repair | 체크섬 재정렬, 실패 기록 제거 | 사고 수습. 남용 금지 |
clean | 스키마의 모든 객체 삭제 | 로컬 초기화 전용 |
clean은 스키마의 테이블, 뷰, 함수를 전부 지웁니다. 운영 DB에서 실행하면 그날로 끝입니다. 최근 버전의 Flyway는 이 명령을 기본으로 막아 두었고(cleanDisabled 기본값 true), 쓰려면 명시적으로 풀어야 합니다. 운영 설정에서는 절대 풀지 마세요. 로컬 초기화가 필요하면 차라리 DB 컨테이너를 지우고 다시 띄우는 편이 안전합니다.
실전에서 밟는 함정
MySQL에는 DDL 트랜잭션이 없습니다
PostgreSQL은 대부분의 DDL을 트랜잭션 안에서 처리합니다. 마이그레이션이 중간에 실패하면 그 파일의 변경이 통째로 롤백됩니다.
MySQL과 Oracle은 그렇지 않습니다. DDL 하나하나가 암묵적으로 커밋됩니다. 한 파일 안에 ALTER TABLE이 세 개 있고 두 번째에서 실패하면, 첫 번째는 적용된 채 남고 flyway_schema_history에는 실패로 기록됩니다. DB가 어중간한 상태가 됩니다.
대응은 두 가지입니다. 파일 하나에 변경 하나만 담아서 실패 지점을 명확하게 만들고, 실패했을 때는 남은 변경을 손으로 되돌린 뒤 repair로 실패 기록을 지우고 다시 실행합니다.
대용량 테이블의 ALTER는 락을 겁니다
스테이징에서 0.2초에 끝난 ALTER TABLE이 운영에서 40분 동안 테이블을 잠그는 일은 흔합니다. 데이터 양이 다르기 때문입니다. 마이그레이션은 운영과 비슷한 규모의 데이터에서 시간을 재 보고 배포해야 합니다.
규모가 크다면 Flyway 안에서 ALTER를 돌리지 않는 선택지도 있습니다. MySQL이라면 pt-online-schema-change나 gh-ost로 무중단 변경을 하고, Flyway에는 그 결과를 반영하는 기록용 마이그레이션만 남깁니다. PostgreSQL이라면 인덱스는 CREATE INDEX CONCURRENTLY를 씁니다. 다만 이 구문은 트랜잭션 안에서 실행할 수 없으므로 별도 파일로 분리하고 해당 마이그레이션의 트랜잭션을 꺼야 합니다.
테스트에서는 마이그레이션을 그대로 씁니다
테스트용으로 ddl-auto: create-drop을 쓰고 싶은 유혹이 있습니다. 빠르니까요. 하지만 그러면 테스트가 검증하는 스키마와 운영에 배포되는 스키마가 다른 것이 됩니다. 마이그레이션에 문법 오류가 있어도 테스트는 통과합니다.
Testcontainers로 실제 DB를 띄우고 Flyway를 그대로 돌리는 편이 낫습니다. 이렇게 하면 마이그레이션 자체가 매 테스트마다 검증됩니다.
spring:
flyway:
enabled: true
locations:
- classpath:db/migration
- classpath:db/testdata
jpa:
hibernate:
ddl-auto: validate
테스트 전용 데이터는 db/testdata에 따로 두고, 운영 설정에서는 이 경로를 넣지 않습니다. 앞서 말한 대로 locations는 기본값을 덮어쓰므로 classpath:db/migration을 반드시 함께 적어야 합니다.
여러 인스턴스가 동시에 뜰 때
Kubernetes에서 파드 세 개가 동시에 시작하면 Flyway도 세 번 실행됩니다. Flyway는 DB 락으로 이 상황을 처리하므로 마이그레이션이 중복 실행되지는 않습니다. 한 인스턴스가 실행하는 동안 나머지는 기다립니다.
다만 마이그레이션이 오래 걸리면 나머지 파드의 기동이 그만큼 늦어지고, 헬스체크 타임아웃에 걸릴 수 있습니다. 마이그레이션이 무거워지는 시점부터는 앱 시작에서 분리해 배포 파이프라인의 별도 단계(예: Kubernetes Job)로 빼는 것을 고려하세요.
Flyway와 Liquibase
같은 문제를 푸는 도구가 하나 더 있습니다. 고르는 기준은 대체로 단순합니다.
| Flyway | Liquibase | |
|---|---|---|
| 마이그레이션 작성 | SQL 파일 그대로 | XML/YAML/JSON changelog 또는 SQL |
| 학습 비용 | 낮음. SQL을 알면 끝 | changelog 문법을 익혀야 함 |
| 롤백 | Enterprise 전용, 수동 작성 | 무료 버전에서 일부 자동 생성 |
| DB 이식성 | SQL을 직접 쓰므로 DB에 종속 | 추상화 계층이 DB 차이를 흡수 |
| 라이선스 | Community 무료(Apache 2.0), Enterprise 유료 | Community 무료, Pro 유료 |
DB를 바꿀 계획이 없고 팀이 SQL에 익숙하다면 Flyway가 편합니다. 배우는 데 하루면 충분하고, 마이그레이션 파일이 그냥 SQL이라 DBA와 같은 언어로 대화할 수 있습니다. 여러 DB 엔진을 동시에 지원해야 하거나 롤백 자동화가 요구 사항이라면 Liquibase를 봅니다.
도입 순서 정리
다음 주에 실제로 도입한다면 이 순서로 하면 됩니다.
- 로컬에서 먼저 익힙니다. 빈 DB에
V1,V2를 만들어 보고flyway_schema_history를 직접 조회해 봅니다. 여기까지 한 시간이면 됩니다. - 운영 스키마를 덤프해
V1__baseline.sql을 만듭니다. 빈 DB에서 재현되는지diff로 검증합니다. 여기가 가장 오래 걸립니다. - 개발 환경에 먼저 적용합니다. baseline을 찍고
flyway info로 상태를 확인합니다. - 팀 규칙을 문서로 합의합니다. 앞의 네 가지를 팀 위키나
CONTRIBUTING.md에 적습니다. 도구보다 이쪽이 오래 갑니다. - 운영에 적용합니다. 적용 후
baseline-on-migrate를false로 되돌립니다. ddl-auto를validate로 바꿉니다. 이제 스키마를 바꾸는 경로는 마이그레이션 파일 하나뿐입니다.
마치며
Flyway가 해 주는 일은 생각보다 소박합니다. SQL 파일을 순서대로 한 번씩 실행하고 기록을 남길 뿐입니다. 마법 같은 것은 없습니다.
그런데 이 소박한 규칙이 생기고 나면, DB 스키마가 "누군가 관리하고 있을 것으로 믿는 무언가"에서 "PR에서 리뷰하고 git으로 추적하는 코드"로 바뀝니다. 신규 입사자가 첫날 ./gradlew bootRun 한 번으로 최신 스키마를 갖게 되고, 배포 전에 어떤 DDL이 나갈지 미리 볼 수 있게 됩니다.
도입하기 가장 좋은 시점은 프로젝트 첫날이고, 그 다음으로 좋은 시점은 오늘입니다. 테이블이 늘어날수록 baseline을 뜨는 일만 어려워집니다.