Search

버전 관리 트레이드 오프

Created
2024/11/06 00:58
태그
설계
Status
Done

문제 상황

프로젝트 목표에 따라 역량검사 3.0 개발을 하게되면서, 기존의 역량검사 2.1과 호환되도록 구현해야 한다. 그 설계 과정에서의 어떤 방식을 선택할 지 고민이 발생했다. 현재 상황에 따라 좋은 선택을 하기 위해 트레이드 오프를 분석해보자.

배경

기존 역량검사의 결과는 결과지 테이블의 value 컬럼에 JSON 형태로 저장되어 있다. 결과지 테이블에는 value 컬럼 외에도 응시 시간이나 응시 버전 등의 응시 관련 정보들을 담고 있다.
1.
MongoDB와 같은 NoSQL에 저장하기
2.
V3 전용 결과 테이블 생성 후 별도로 저장하기
3.
JSON으로 저장되어 있는 김에 인터페이스로 추상화하기
4.
V2와 V3의 필드들을 전부 하나에 때려넣고 사용하지 않는 값 null로 받기
5.
실질적으로 결과를 저장하는 필드인 JSON 데이터만 별도로 테이블 분리하여 외래키 참조

트레이드 오프 분석

트레이드 오프 비교하기

방식
장점
단점
1. MongoDB에 저장
• 스키마 유연성으로 내부 항목을 쉽게 변경 가능 • 대용량 데이터 확장성
• 추가적인 인프라 설정 및 관리 필요 • 제한적인 트랜잭션 처리 • 기존의 V2 데이터 마이그레이션 필요
2. 새 테이블에 저장
• 리소스를 별도로 관리하기 때문에 버전 관리 측면에서 유리 • 솔루션 개념
• 이전 버전의 역량검사 데이터 마이그레이션 요청 시 문제 발생 • 새 테이블 추가에 따른 CRUD의 새로운 구현 및 추상화 로직 필요 • 새 테이블과 기존 테이블에 상당수 필드가 중복 • 매 버전 추가 시마다 새로운 테이블 추가
3. 인터페이스 추상화
• 이후 새로운 버전 추가 시 구현 용이 • 효율적 리소스 관리(적은 테이블, 적은 비즈니스 로직) • 기존 로직의 재사용 가능
• 인터페이스 캐스팅에 대한 리스크 • 초기 설계 비용(데이터 추상화 및 컨버터 구현)
4. 필드 추가
• 구현이 간단 • 기존 로직의 재사용 가능 • 단일 객체로 관리 + 기존 로직 재사용으로 인해 안정성이 높음
• 버전 추가 시 수많은 필드 추가로 인해 지저분해질 가능성 • 근시안적 해결 방법
5. 필드만 분리 후 외래키 참조
• 테이블 정규화 개념(중복되는 필드를 해결)
• 이전 버전의 역량검사 조회 및 데이터 마이그레이션 시 문제 발생 • 매우 큰 초기 설계 비용(기존의 JSON으로 저장된 데이터를 테이블 필드로 바꾸어 저장하는 작업 필요 + 새 테이블 및 엔티티에 따른 추가 구현) • 매 버전 추가 시마다 새로운 테이블 추가

애플케이션 및 비즈니스 로직, 프로젝트 고려사항

1.
역량검사 3.0의 경우 기존의 2.1 버전과의 차이는 일부 계산 로직과 그에 따른 결과 항목 변경
2.
역량검사 자체는 MSA로 서비스가 분리되어 있고, 결과는 역량검사 서비스에 저장되며 클라이언트 요청을 받는 상위 서비스는 결과를 받아 비즈니스 로직에 따라 가공만 수행
3.
도메인 이해도 대비 개발 분량이 많아 개발 기간 약간 촉박
4.
결과지 테이블 내 레코드 27223개
5.
현재 역량검사 4.0 설계 중(이후 4.0 개발 예정)
6.
역량검사는 채널별 설정에 따라 지정(역량검사 3.0을 보는 채널 내 모든 응시자는 3.0을 봐야함)

논의 결과 및 적용

현 상황을 보면 확정적으로 개발을 해야하는 부분은 역량검사 선택 결과를 통해 각 항목 점수를 계산하는 계산 로직역량검사 버전에 따라 서로 다른 결과를 응답하도록 하는 부분이다.
먼저 1번 방식의 경우, 추가적인 인프라 구성 필요하다는 점과 제한적인 트랜잭션, V2의 결과가 이미 JSON으로 말려있다는 점, 결과의 항목 자체는 크게 변경될 일이 없다는 점에서 큰 이점을 느끼지 못했다.
새 테이블에 저장하는 2번 방식은, 위에 더해서 새 테이블에 대한 CRUD 부분도 추가적으로 구현해야 한다. 또한 이는 이후 역량검사 4.0 개발 시에 동일하게 적용되는 부분이다. 또한 기존 테이블과 많은 데이터가 중복되어 리소스를 비효율적으로 관리하게 된다.
만약 역량검사 응시 과정 자체가 바뀌어 API를 별도로 분리할 필요가 있다면 적합한 방법일 수 있지만, 현 상황에서는 적합하지 않다고 판단된다.
또한 필드만을 테이블로 분리하고 외래키를 통해 저장하는 5번 방식은 매 버전마다 테이블이 추가되고 그에 따라 CRUD의 추가적인 구현이 필요하다는 단점을 그대로 가진다. 거기에 더해 결과지 테이블의 27223개의 레코드를 오류 없이 새로운 테이블로 마이그레이션 + 외래키 참조를 수행해야하며, 실제 서비스에서 사용되는 데이터인만큼 그 과정에서 데이터의 유실이나 손실 없이 완성해야한다.
장기적인 관점과 리소스의 효율적인 관리 측면에서는 이 방법이 최선의 선택일 수 있으나, 실제 운영 중인 서비스의 데이터를 새 테이블로 마이그레이션하는 리스크와 촉박한 개발 기간 대비 가장 큰 초기 설계 비용으로 인해 선택하지 않기로 했다.
JSON 데이터를 인터페이스로 추상화하는 3번 방식과 JSON 데이터에 각 버전에 필요한 값을 전부 때려박는 4번 방식 중에 많은 고민을 했고, 현재 역량검사의 점수 통계에 대한 별도의 통계용 테이블이 존재하고 역량검사 결과에 대한 필터링 요청이 없다는 점에서 인터페이스로 추상화하는 방식을 선택했다. 또한 곧이어 역량검사 4.0 개발이 예정되어있다는 점에서도 합리적으로 느껴진다.
결론적으로 4.0 버전이 추가되었을 때, 인터페이스 추상화 방식은 컨버터와 추상 로직의 일부만 수정하면 된다는 장점을 가진다. 반면 필드 추가 방식은 4.0에서 사용되는 새로운 필드들이 추가되어 객체가 매우 지저분해질 가능성이 농후하다는 점에서도 별로라고 생각이 들었다.