Skip to content

Comments

flyway: Flyway 도입 및 V1 초기 스키마 마이그레이션 파일 추가#171

Merged
ryuwldnjs merged 3 commits intomainfrom
169-infra-flyway-도입으로-db-마이그레이션-자동화
Feb 22, 2026

Hidden character warning

The head ref may contain hidden characters: "169-infra-flyway-\ub3c4\uc785\uc73c\ub85c-db-\ub9c8\uc774\uadf8\ub808\uc774\uc158-\uc790\ub3d9\ud654"
Merged

flyway: Flyway 도입 및 V1 초기 스키마 마이그레이션 파일 추가#171
ryuwldnjs merged 3 commits intomainfrom
169-infra-flyway-도입으로-db-마이그레이션-자동화

Conversation

@ryuwldnjs
Copy link
Member

@ryuwldnjs ryuwldnjs commented Feb 22, 2026

관련 이슈

변경 내용

변경 유형

  • [FEATURE] 기능 구현
  • [BUG] 버그 수정
  • [REFACTOR] 리팩토링
  • [CHORE] 설정/의존성
  • [DOCS] 문서

테스트

  • 테스트 완료

스크린샷 (UI 변경 시)

참고사항

Summary by CodeRabbit

  • 새 기능

    • 데이터베이스 마이그레이션 도입(Flyway) 및 초기 스키마와 광범위한 시드 데이터 추가(문제, 태그, 회원, 팀 등)
  • 설정

    • 개발/테스트/프로덕션별 마이그레이션 동작 구성 추가
    • 로컬에서 baseline 설정 및 검증 모드 전환(spring.jpa.hibernate.ddl-auto 변경), 테스트 환경에서는 마이그레이션 비활성화

@ryuwldnjs ryuwldnjs linked an issue Feb 22, 2026 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'path_filters'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

No actionable comments were generated in the recent review. 🎉


Walkthrough

애플리케이션에 Flyway 기반 DB 마이그레이션을 도입하고 공통·환경별 Flyway 설정을 추가했으며, 프로덕션 현재 스키마를 담은 초기 마이그레이션 파일 V1__init_schema.sql을 추가했습니다.

Changes

Cohort / File(s) Summary
의존성 추가
build.gradle
org.flywaydb:flyway-mysql 의존성 추가.
공통 설정
src/main/resources/application.yml
Flyway 공통 설정(spring.flyway.locations: classpath:db/migration) 추가.
로컬 설정
src/main/resources/application-local.yml
spring.flyway.baseline-on-migrate: true, baseline-version: 1 추가; spring.jpa.hibernate.ddl-autovalidate로 변경.
프로덕션 설정
src/main/resources/application-prod.yml
spring.flyway.baseline-on-migrate: true, baseline-version: 1 추가.
테스트 설정
src/main/resources/application-test.yml
테스트 환경에서 Flyway 비활성화(spring.flyway.enabled: false) 추가.
초기 마이그레이션
src/main/resources/db/migration/V1__init_schema.sql
프로덕션 스키마 전체를 초기화하는 V1 SQL 파일 추가(여러 테이블, 인덱스 및 대량 태그 시드 포함).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant App as 애플리케이션
    participant Flyway as Flyway
    participant DB as 데이터베이스
    participant Hibernate as Hibernate

    App->>Flyway: 애플리케이션 시작 시 마이그레이션 스캔/실행
    Flyway->>DB: flyway_schema_history 생성 및 baseline 처리
    alt 신규 마이그레이션 존재
        Flyway->>DB: V2+ 마이그레이션 적용
    end
    App->>Hibernate: 엔티티 ↔ DB 스키마 validate 요청
    Hibernate->>DB: 메타데이터 조회
    Hibernate-->>App: validate 결과 반환
    App->>App: 애플리케이션 기동 완료
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 새벽밭에 폴짝, 마이그레이션 왔네,

V1 깃발 세우고 길 닦는 Flyway,
Hibernate는 눈썹 비비며 확인하고,
개발자는 커피로 환호하네,
토끼도 춤추며 배포를 축하해!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 Flyway 도입 및 V1 초기 스키마 마이그레이션 파일 추가라는 주요 변경사항을 명확하고 간결하게 요약하고 있습니다.
Linked Issues check ✅ Passed 변경사항이 #169의 모든 주요 요구사항을 충족합니다: Flyway 의존성 추가, 환경별 설정 변경, V1 초기 스키마 파일 생성, clean-start 전략 구현, baseline 설정 등이 모두 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 #169의 Flyway 도입 목표와 직접 관련이 있으며, 범위를 벗어난 변경사항이 없습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 169-infra-flyway-도입으로-db-마이그레이션-자동화

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Feb 22, 2026

🧪 테스트 결과

145 tests   143 ✅  3s ⏱️
 30 suites    2 💤
 30 files      0 ❌

Results for commit 31eeea0.

♻️ This comment has been updated with latest results.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/main/resources/application-local.yml (2)

57-59: 로컬 환경의 로그 레벨을 WARN으로 낮추면 디버깅이 어렵습니다

com.ryu.studyhelper, org.springframework.security, org.hibernate.SQL 모두 DEBUG에서 WARN으로 변경되었습니다. 로컬 개발 환경에서는 애플리케이션 로직, 보안 필터, SQL 쿼리를 DEBUG 수준으로 추적할 수 있어야 문제 진단이 용이합니다.

💡 로컬 디버깅을 위한 로그 레벨 복원 제안
-    com.ryu.studyhelper: WARN
-    org.springframework.security: WARN
-    org.hibernate.SQL: WARN
+    com.ryu.studyhelper: DEBUG
+    org.springframework.security: DEBUG
+    org.hibernate.SQL: DEBUG
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/application-local.yml` around lines 57 - 59, The log
levels for local development have been lowered to WARN for com.ryu.studyhelper,
org.springframework.security, and org.hibernate.SQL which hinders debugging;
update application-local.yml to restore these logger entries to DEBUG (set
com.ryu.studyhelper: DEBUG, org.springframework.security: DEBUG, and
org.hibernate.SQL: DEBUG) so application logic, security filters, and SQL
queries are traceable during local development.

29-32: 로컬 환경에서 show-sql과 SQL 로그 수준을 낮추면 디버깅이 어렵습니다

show-sql: falseformat_sql: false는 개발 중 실행되는 쿼리를 콘솔에서 확인할 수 없게 만듭니다. 로컬 환경에서는 일반적으로 SQL 가시성이 유용합니다. 아래 설정을 유지하는 편이 개발 경험에 더 적합합니다.

💡 로컬 개발 친화적인 설정 제안
-    show-sql: false
+    show-sql: true
   properties:
     hibernate:
-      format_sql: false
+      format_sql: true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/application-local.yml` around lines 29 - 32, Enable SQL
visibility for local development by setting show-sql to true and
properties.hibernate.format_sql to true in the local application config; update
the entries named show-sql and properties.hibernate.format_sql so that SQL
statements are printed and formatted to the console for easier debugging in the
local environment.
src/main/resources/db/migration/V1__init_schema.sql (2)

290-330: 자주 조회되는 컬럼에 인덱스가 누락되어 있습니다

member_solved_problemteam_member 테이블에 인덱스가 없어 핵심 쿼리 경로에서 풀 테이블 스캔이 발생합니다.

테이블 빠진 인덱스 예상 쿼리 패턴
member_solved_problem (member_id) 또는 (member_id, problem_id) 특정 멤버의 풀이 이력 조회
team_member (team_id), (member_id) 팀 멤버 목록 / 멤버가 속한 팀 조회
📌 인덱스 추가 제안
  -- 5. member_solved_problem
  CREATE TABLE member_solved_problem ( ... );

+ CREATE INDEX idx_member_solved_problem_member ON member_solved_problem (member_id);
+ CREATE INDEX idx_member_solved_problem_problem ON member_solved_problem (problem_id);

  -- 7. team_member
  CREATE TABLE team_member ( ... );

+ CREATE INDEX idx_team_member_team ON team_member (team_id);
+ CREATE INDEX idx_team_member_member ON team_member (member_id);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/db/migration/V1__init_schema.sql` around lines 290 - 330,
Add appropriate indexes to avoid full table scans: after the
member_solved_problem table definition create an index on member_id (or a
composite index on (member_id, problem_id)) and after the team_member table
definition create indexes on team_id and on member_id; update the
V1__init_schema.sql migration by appending CREATE INDEX statements referencing
the table/column names (member_solved_problem(member_id) or
member_solved_problem(member_id, problem_id), team_member(team_id),
team_member(member_id)) so queries like "member's solved history" and "team
members / member's teams" use the indexes.

732-757: recommendation_problemmember_recommendation 테이블에 인덱스 누락

recommendation_id 컬럼을 기준으로 조회하는 경우 인덱스가 없어 풀 스캔이 발생합니다.

📌 인덱스 추가 제안
  CREATE TABLE recommendation_problem ( ... );

+ CREATE INDEX idx_rec_problem_recommendation ON recommendation_problem (recommendation_id);

  CREATE TABLE member_recommendation ( ... );

+ CREATE INDEX idx_member_rec_recommendation ON member_recommendation (recommendation_id);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/db/migration/V1__init_schema.sql` around lines 732 - 757,
Add explicit non-unique indexes on the recommendation_id column for both tables
so queries filtering by recommendation_id avoid full table scans: add an index
named like idx_recommendation_problem_recommendation_id on
recommendation_problem(recommendation_id) and another like
idx_member_recommendation_recommendation_id on
member_recommendation(recommendation_id) in the V1__init_schema.sql migration
near the CREATE TABLE blocks for recommendation_problem and
member_recommendation; note the existing uk_member_recommendation (member_id,
recommendation_id) is a composite index that cannot be used when filtering only
by recommendation_id, so the separate single-column indexes are required.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/resources/db/migration/V1__init_schema.sql`:
- Around line 357-830: This file contains duplicated schema blocks (duplicate
CREATE TABLE and CREATE INDEX statements for tag, problem, problem_tag, member,
member_solved_problem, team, team_member, team_include_tag, team_join,
recommendation, recommendation_problem, member_recommendation, notification and
repeated indexes like idx_requester_status/idx_target_status/idx_team_status)
causing fresh migrations to fail; remove the redundant copy and keep a single
canonical schema that includes the team_join indexes and the recommendation /
recommendation_problem / member_recommendation / notification definitions (the
unique correct content found in the 717–773 region), ensure each table (e.g.,
tag, problem, team_join, recommendation, recommendation_problem,
member_recommendation, notification) and each index (e.g., idx_requester_status,
idx_target_status, idx_team_status, idx_recipient, idx_problem_tag_problem,
idx_problem_tag_tag, idx_team_include_tag_tag, idx_team_include_tag_team) is
declared exactly once, and delete the entire duplicated block(s) that re-declare
these tables and indexes so Flyway can run a clean, non-conflicting full-schema
create.

---

Nitpick comments:
In `@src/main/resources/application-local.yml`:
- Around line 57-59: The log levels for local development have been lowered to
WARN for com.ryu.studyhelper, org.springframework.security, and
org.hibernate.SQL which hinders debugging; update application-local.yml to
restore these logger entries to DEBUG (set com.ryu.studyhelper: DEBUG,
org.springframework.security: DEBUG, and org.hibernate.SQL: DEBUG) so
application logic, security filters, and SQL queries are traceable during local
development.
- Around line 29-32: Enable SQL visibility for local development by setting
show-sql to true and properties.hibernate.format_sql to true in the local
application config; update the entries named show-sql and
properties.hibernate.format_sql so that SQL statements are printed and formatted
to the console for easier debugging in the local environment.

In `@src/main/resources/db/migration/V1__init_schema.sql`:
- Around line 290-330: Add appropriate indexes to avoid full table scans: after
the member_solved_problem table definition create an index on member_id (or a
composite index on (member_id, problem_id)) and after the team_member table
definition create indexes on team_id and on member_id; update the
V1__init_schema.sql migration by appending CREATE INDEX statements referencing
the table/column names (member_solved_problem(member_id) or
member_solved_problem(member_id, problem_id), team_member(team_id),
team_member(member_id)) so queries like "member's solved history" and "team
members / member's teams" use the indexes.
- Around line 732-757: Add explicit non-unique indexes on the recommendation_id
column for both tables so queries filtering by recommendation_id avoid full
table scans: add an index named like
idx_recommendation_problem_recommendation_id on
recommendation_problem(recommendation_id) and another like
idx_member_recommendation_recommendation_id on
member_recommendation(recommendation_id) in the V1__init_schema.sql migration
near the CREATE TABLE blocks for recommendation_problem and
member_recommendation; note the existing uk_member_recommendation (member_id,
recommendation_id) is a composite index that cannot be used when filtering only
by recommendation_id, so the separate single-column indexes are required.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
src/main/resources/db/migration/V1__init_schema.sql (3)

290-300: member_solved_problem에 조회용 인덱스 누락

member_idproblem_id 컬럼에 인덱스가 없습니다. "특정 멤버가 푼 문제 목록 조회"와 같은 핵심 쿼리가 전체 테이블 스캔으로 처리될 수 있습니다.

⚡️ 인덱스 추가 제안
 CREATE TABLE member_solved_problem
 (
     ...
 );
+
+CREATE INDEX idx_member_solved_member ON member_solved_problem (member_id);
+CREATE INDEX idx_member_solved_problem ON member_solved_problem (problem_id);

또한 동일한 멤버가 동일 문제를 중복 등록하는 것을 방지해야 한다면 UNIQUE 제약도 함께 고려해 주세요.

-- 비즈니스 로직상 중복 풀이 기록이 불필요하다면:
ALTER TABLE member_solved_problem
    ADD CONSTRAINT uk_member_problem UNIQUE (member_id, problem_id);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/db/migration/V1__init_schema.sql` around lines 290 - 300,
The member_solved_problem table lacks indexes on member_id and problem_id which
can cause full table scans for queries like "get problems solved by a member";
add appropriate indexes on member_id and problem_id (and consider a composite
index on (member_id, problem_id) for common query patterns) and, if duplicate
solves must be prevented, add a UNIQUE constraint on (member_id, problem_id).
Update the migration to create these indexes/constraint for the
member_solved_problem table so queries using member_id/problem_id use the new
indexes and duplicates are prevented when required.

250-258: 일부 테이블에 COLLATE 미지정 — 콜레이션 불일치 잠재 위험

problem, member, team, team_join, notification 등 일부 테이블은 COLLATE = utf8mb4_unicode_ci가 명시되지 않아 DB 서버 기본값을 그대로 상속합니다. MySQL 8.0에서 utf8mb4의 기본 콜레이션은 utf8mb4_0900_ai_ci이므로, 명시적으로 utf8mb4_unicode_ci를 지정한 테이블(예: tag, problem_tag, team_include_tag)과 혼재될 경우 utf8mb4_unicode_ciutf8mb4_0900_ai_ci가 혼용된 컬럼 간 비교 시 Illegal mix of collations 오류(Error 1267)가 발생할 수 있습니다.

특히 problem.title_ko(varchar(255)) 및 team.name, team.description 컬럼은 한글을 저장하는 필드인데, 서버 기본값이 utf8mb4_unicode_ci가 아닌 환경에서 마이그레이션하면 정렬·비교 동작이 달라질 수 있습니다. 이 파일에서 COLLATE를 명시한 테이블과 나머지 테이블의 기준을 통일하는 것을 권장합니다.

♻️ 콜레이션 명시 예시 (대표 테이블)
 CREATE TABLE problem
 (
     id                  bigint       NOT NULL PRIMARY KEY,
     accepted_user_count int          NULL,
     level               int          NULL,
     title               varchar(255) NOT NULL,
     title_ko            varchar(255) NULL,
     average_tries       double       NULL
-);
+) COLLATE = utf8mb4_unicode_ci;

 CREATE TABLE team
 (
     ...
     name                      varchar(255)                               NOT NULL,
     ...
-);
+) COLLATE = utf8mb4_unicode_ci;

 CREATE TABLE notification
 (
     ...
     metadata     text        NULL,
     ...
-);
+) COLLATE = utf8mb4_unicode_ci;

Also applies to: 272-288, 302-318, 344-362, 402-415

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/db/migration/V1__init_schema.sql` around lines 250 - 258,
Several tables (e.g., problem, member, team, team_join, notification) lack
explicit COLLATE settings causing potential mixed-collation errors with tables
that use utf8mb4_unicode_ci (e.g., tag, problem_tag, team_include_tag); update
the CREATE TABLE statements for these tables to specify CHARSET utf8mb4 and
COLLATE utf8mb4_unicode_ci (also ensure varchar columns like problem.title_ko,
team.name, team.description inherit that collation) so all schema DDL uses the
same charset/collation consistently to avoid Illegal mix of collations errors.

375-400: recommendation_problem, member_recommendationrecommendation_id 인덱스 누락

두 테이블 모두 recommendation_id로 조회하는 패턴(특정 추천의 문제 목록, 특정 추천을 받은 멤버 목록)이 빈번할 것으로 예상되지만 해당 컬럼에 인덱스가 없습니다. member_recommendation의 UNIQUE 인덱스는 (member_id, recommendation_id) 순서라 recommendation_id 단독 조회에는 활용되지 않습니다.

⚡️ 인덱스 추가 제안
 CREATE TABLE recommendation_problem
 (
     ...
 ) COLLATE = utf8mb4_unicode_ci;
+
+CREATE INDEX idx_rec_problem_rec ON recommendation_problem (recommendation_id);

 CREATE TABLE member_recommendation
 (
     ...
 ) COLLATE = utf8mb4_unicode_ci;
+
+CREATE INDEX idx_member_rec_rec ON member_recommendation (recommendation_id);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/db/migration/V1__init_schema.sql` around lines 375 - 400,
Add a single-column index on recommendation_id for both tables to speed lookups:
modify the migration to create an index on
recommendation_problem.recommendation_id (e.g.,
idx_recommendation_problem_recommendation_id) and another on
member_recommendation.recommendation_id (e.g.,
idx_member_recommendation_recommendation_id); keep the existing
uk_member_recommendation unique constraint as-is since its (member_id,
recommendation_id) order doesn't help single-column recommendation_id queries.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/main/resources/db/migration/V1__init_schema.sql`:
- Around line 290-300: The member_solved_problem table lacks indexes on
member_id and problem_id which can cause full table scans for queries like "get
problems solved by a member"; add appropriate indexes on member_id and
problem_id (and consider a composite index on (member_id, problem_id) for common
query patterns) and, if duplicate solves must be prevented, add a UNIQUE
constraint on (member_id, problem_id). Update the migration to create these
indexes/constraint for the member_solved_problem table so queries using
member_id/problem_id use the new indexes and duplicates are prevented when
required.
- Around line 250-258: Several tables (e.g., problem, member, team, team_join,
notification) lack explicit COLLATE settings causing potential mixed-collation
errors with tables that use utf8mb4_unicode_ci (e.g., tag, problem_tag,
team_include_tag); update the CREATE TABLE statements for these tables to
specify CHARSET utf8mb4 and COLLATE utf8mb4_unicode_ci (also ensure varchar
columns like problem.title_ko, team.name, team.description inherit that
collation) so all schema DDL uses the same charset/collation consistently to
avoid Illegal mix of collations errors.
- Around line 375-400: Add a single-column index on recommendation_id for both
tables to speed lookups: modify the migration to create an index on
recommendation_problem.recommendation_id (e.g.,
idx_recommendation_problem_recommendation_id) and another on
member_recommendation.recommendation_id (e.g.,
idx_member_recommendation_recommendation_id); keep the existing
uk_member_recommendation unique constraint as-is since its (member_id,
recommendation_id) order doesn't help single-column recommendation_id queries.

@ryuwldnjs ryuwldnjs merged commit 339f089 into main Feb 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[INFRA] Flyway 도입으로 DB 마이그레이션 자동화

1 participant