블로그 이미지

suddiyo


꾸준히 기록하고 성장하는 백엔드 개발자 💻
Today
-
Yesterday
-
Total
-

ABOUT ME

-

  • [Briefing] Flyway로 DB 스키마 형상 관리하기 - 2
    Project/Briefing 2024. 3. 9. 15:04

    📝 지난 포스팅

    ➡︎ Flyway로 DB 스키마 형상 관리하기 - 1

     

    [Briefing] Flyway로 DB 스키마 형상 관리하기 - 1

    Briefing 프로젝트를 진행하는 과정에서 엔티티간 매핑 변동으로 인해 DB 스키마 수정이 필요하게 되었다. 초기 개발 단계가 아닌 런칭이 된 서비스고 실사용자가 존재하기 때문에, 기존 데이터를

    suddiyo.tistory.com


    지난 포스팅에서 Flyway의 자동 원리를 알아봤으니 이번 포스팅에서는 간단한 예제를 통해 마이그레이션 테스트를 진행할 것이다.

    최대한 프로젝트 환경과 비슷하게 진행하기 위하여,

     

    TeamMember라는 중간 테이블을 통해 매핑되어있는 N:N 관계의 Team과 Member를

    flyway를 통해 N:1 관계로 마이그레이션하는 실습을 진행해보자 !


    1️⃣ 테스트용 데이터 생성

    Member.java

    @Entity
    public class Member {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String name;
    
        private int age;
    
    }

     

    Team.java

    @Entity
    public class Team {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String name;
    
    }

     

    TeamMember.java

    @Entity
    public class TeamMember {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @ManyToOne(fetch = FetchType.LAZY)
        private Member member;
    
        @ManyToOne(fetch = FetchType.LAZY)
        private Team team;
    
    }

     

    다음과 같이 member, team, team_member 세 개의 테이블이 생성된 것을 확인할 수 있다.

    마이그레이션의 작동을 확인하기 위하여 더미데이터를 넣어주었다.

    flyway DB

     


    2️⃣ Flyway 의존성 추가

    build.gradle에 Flyway 의존성을 추가한다.

     

    build.gradle

    // Flyway
    implementation 'org.flywaydb:flyway-core'
    implementation 'org.flywaydb:flyway-mysql'

     


    3️⃣ application.yml 설정

    application.yml에서 flyway를 활성화하고, 관련 설정을 구성한다.

     

    application.yml

    spring:
      flyway:
        enabled: true
        baseline-on-migrate: true
        baseline-version: 0
    
      jpa:
        hibernate:
          ddl-auto: update

     

    - 기존 데이터베이스를 기반으로 마이그레이션을 진행하기 위하여 baseline-on-migrate 설정을 활성화했다.

    - 초기 기준 버전을 0으로 설정함으로써, 마이그레이션 스크립트의 버전 번호를 1부터 시작하도록 했다.

    +) 개발 편의성을 위해 ddl-auto 옵션을 update로 설정해줬지만, 프로덕션 환경에서는 안전하게 none으로 설정하는 게 좋다고 한다.

     


    4️⃣ Entity 매핑 변경

    Member:Team 의 관계를 N:N → 1:N으로 변경한다.

     

    Member.java

    @Entity
    public class Member {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String name;
    
        private int age;
    
        @ManyToOne(fetch = FetchType.LAZY)
        private Team team;
    
    }

     

    Team.java

    @Entity
    public class Team {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String name;
    
        @OneToMany(mappedBy = "team")
        private List<Member> members;
    
    }

     

    * TeamMember 엔티티는 삭제했다.

     


    5️⃣ flyway 마이그레이션 스크립트 작성

    resources > db > migration 디렉토리 내에

    V1__change_NN_to_N1_relationship.sql 이라는 파일을 생성하여 마이그레이션 스크립트를 작성한다.

     

    V1_change_NN_to_N1_relationship.sql

    ALTER TABLE member ADD COLUMN team_id BIGINT;
    
    -- 기존 team_member 데이터를 기반으로 member 테이블의 team_id 업데이트
    UPDATE Member m
    JOIN team_member tm ON m.id = tm.member_id
    SET m.team_id = tm.team_id;
    
    -- 더 이상 필요 없는 team_member 테이블 제거
    DROP TABLE team_member;
    1. member 테이블에 team_id 컬럼을 추가하여, team_member 테이블을 거쳐가지 않고 직접 참조할 수 있도록 한다.
    2. 기존의 team_member 테이블을 사용하여 member 테이블 내의 team_id 값을 업데이트한다.
    3. 마이그레이션을 마치게 되면 team_member 테이블이 더 이상 필요하지 않기 때문에 삭제한다.

     


    6️⃣ Application 실행 및 결과 확인

    데이터베이스 형상 관리를 위해 flyway에 의해 생성된 flyway_schedma_history 테이블을 확인할 수 있다.

    이 테이블에는 다음과 같이 version, description, success 등의 컬럼이 존재한다.

    team_memer 테이블도 정상적으로 drop 됨 !

     

    1️⃣에서 넣어놨던 데이터들도 정상적으로 마이그레이션 되어 올바른 team_id를 가지고 있는 것을 확인할 수 있었다.

     

    728x90

    'Project > Briefing' 카테고리의 다른 글

    [Briefing] Flyway로 DB 스키마 형상 관리하기 - 1  (2) 2024.03.08

    댓글

Designed by Tistory.