- 배포된 데이터베이스의 스키마를 변경해보자(2)2025년 03월 15일 00시 31분 59초에 업로드 된 글입니다.작성자: do_hyuk
이전 글에서도 말했듯이 이번 포스팅에서는 로컬 데이터베이스에 스키마 구조를 변경해보고 flyway를 통해 제대로 적용이 되는지 확인해보겠다.
Entity 구조 변경
ddl-auto: validate 로 설정해뒀기 때문에 Entity와 DB 테이블의 구조가 같은지 비교하고 유효성 검사를 위해 앞으로 변경할 DB 스키마 구조에 맞게 entity도 변경해줘야 한다.
Member Entity와 연관관계 매핑 되있던 것을 끊고 회원 아이디, 이메일, 닉네임 컬럼을 추가한다.
현재 CodePost, TILPost 테이블 두 개가 존재하기 때문에 각 Entity 구조를 아래와 같이 변경하면 되겠다.
연관관계와 관련된 로직들의 수정 코드는 따로 작성하지는 않겠다.
// member 컬럼 삭제 // @ManyToOne(fetch = FetchType.LAZY) // @JoinColumn // private Member member; // member 관련 컬럼 추가 @Column(nullable = false) private Long writerId; @Column(nullable = false) private String writerEmail; @Column(nullable = false) private String writerNickName;
Member Entity에서도 아래와 같은 코드를 삭제한다.
// 삭제 //@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) //private List<CodePost> codePosts = new ArrayList<>(); //@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) //private List<TILPost> tilPosts = new ArrayList<>();
Flyway 스크립트 작성
스크립트 작성 시 주의해야할 점으로는 table에 컬럼을 추가만 해서는 안된다.
현재 db에 이미 회원을 외래키로 가지고 있는 데이터가 존재하기 때문에 외래키를 삭제하고 컬럼을 추가만 한다면 데이터 유실 문제가 생기기 때문이다. 따라서 작성자에 대한 정보도 옮겨야한다.
V2__XXX.sql
-- CodePost 테이블에 writer_id, writer_email, writer_nickname 컬럼 추가 ALTER TABLE code_post ADD COLUMN writer_id BIGINT, ADD COLUMN writer_email VARCHAR(255), ADD COLUMN writer_nickname VARCHAR(255); -- TILPost 테이블에 writer_id, writer_email, writer_nickname 컬럼 추가 ALTER TABLE tilpost ADD COLUMN writer_id BIGINT, ADD COLUMN writer_email VARCHAR(255), ADD COLUMN writer_nickname VARCHAR(255); -- 기존 member_id 값을 writer_id로 복사 UPDATE code_post cp SET cp.writer_id = cp.member_id WHERE cp.member_id IS NOT NULL; -- member_id가 NULL이 아닌 경우에만 업데이트 UPDATE tilpost tp SET tp.writer_id = tp.member_id WHERE tp.member_id IS NOT NULL; -- member_id가 NULL이 아닌 경우에만 업데이트 -- writer_id를 기준으로 writer_email, writer_nickname 업데이트 UPDATE code_post cp JOIN Member m ON cp.writer_id = m.id SET cp.writer_email = m.email, cp.writer_nickname = m.nickname WHERE cp.writer_id IS NOT NULL; -- writer_id가 NULL이 아닌 경우에만 업데이트 UPDATE tilpost tp JOIN Member m ON tp.writer_id = m.id SET tp.writer_email = m.email, tp.writer_nickname = m.nickname WHERE tp.writer_id IS NOT NULL; -- writer_id가 NULL이 아닌 경우에만 업데이트 -- CodePost 테이블에서 member 외래 키 제거 ALTER TABLE code_post DROP FOREIGN KEY 외래키; -- TILPost 테이블에서 member 외래 키 제거 ALTER TABLE tilpost DROP FOREIGN KEY 외래키; -- CodePost 테이블에서 member 컬럼 제거 ALTER TABLE code_post DROP COLUMN member_id; -- TILPost 테이블에서 member 컬럼 제거 ALTER TABLE tilpost DROP COLUMN member_id;
Version 2 스크립트에는 Code/TIL Post 에 새로운 컬럼을 추가 및 데이터 삽입을 하고, 외래키를 삭제하는 쿼리를 작성하였다.
각 테이블에서 member 외래키를 삭제하고 테이블에서 member_id 컬럼을 삭제해 준다.
이제 프로젝트를 재실행하여 로컬 데이터베이스에 제대로 적용이 되는지 확인해보겠다.
결과
스크립트 실행 후 codePost 컬럼 변경됨 flyway_schema_history 테이블에 제대로 성공 내역이 저장됨 제대로 적용된 것을 볼 수 있다.
하지만 수많은 시행착오를 겪으면서 version 2 스크립트를 실패했을 때 이미 flyway_schema_history에 v2의 실패 내역이 저장되면서 해당 버전에 이미 실패한 마이그레이션이 존재한다면 Flyway는 해당 버전을 실행하지 않게 된다.
일단 급한대로 테스트를 하기 위한 로컬 환경이였기에 DB에 직접 접근하여 해당 데이터를 삭제했지만 이건 좋지 못한 접근법이기 때문에 다른 방법이 있는지 찾아봐야겠다.
flyway repair 에 대해 알아봐야겠다.
2025.03.20
'포트폴리오 > AutoReview' 카테고리의 다른 글
[트러블 슈팅] 2개 이상의 데이터베이스 초기화 기능은 사용하지 말자 (0) 2025.03.22 Flyway_Schema_History 테이블 자동 복구하기 (0) 2025.03.20 배포된 데이터베이스의 스키마를 변경해보자(1) (0) 2025.03.11 연관관계 설정은 필수일까? (0) 2025.03.07 K6로 토큰 인증 절차가 필요한 API 테스트 하기 (0) 2025.02.24 댓글