Search

응시자의 QA 완료 시간 필드 추가 시 트레이드 오프 분석

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

배경

현재 QA 여부는 응시자 엔티티 내에 Enum으로 QA 필요 여부를 관리하는 필드가 존재
QA 적용되는 응시자에 대해 QA가 완료된 시점을 알고 싶다는 요구사항에 따라 해당 값을 저장할 필드 추가 필요
해당 필드를 어디에 어떻게 추가할 지에 따른 트레이드 오프를 따져보기 위해 문서 작성

방법과 예시, 장단점

장단점 고려사항

컬럼, 테이블 추가 여부
도메인 응집도
코드의 간결함과 일관성
각 특성에 따라 발생하는 장점과 단점
성능
❗️새로 추가될 QA 완료 시간에 대한 컬럼이 nullable인 것은 모든 케이스에 해당되기 때문에 단점에서 제외하였습니다.

1. 단순히 필드 하나를 추가하여 QA 완료 시점을 저장하는 방법

상황에 따른 예시
QA가 필요없는 경우
QA필요여부 = 불필요 / QA완료시각 = null
QA가 필요한 경우
QA필요여부 = 필요 / QA완료시각 = null
QA가 완료된 경우
QA필요여부 = 통과 / QA완료시각 = 2024-08-09'T'16:09:44
장점
구현이 간단하고 직관적
특정 조건에 따라 쿼리로만 필터링 수행 가능 (ex. QA 완료 응시자 필터링)
단점
추가적인 컬럼을 사용해야함
응시자 도메인의 로직이 뚱뚱해짐(현재도 충분히 뚱뚱하다)

2. JSON으로 저장

상황에 따른 예시
QA가 필요없는 경우
DB - "{"QA필요여부":"불필요"}"
객체 - QA필요여부 = 불필요 / QA완료시각 = null
QA가 필요한 경우
DB - "{"QA필요여부":"필요"}"
객체 - QA필요여부 = 필요 / QA완료시각 = null
QA가 완료된 경우
DB - "{"QA필요여부":"통과", "QA완료시각":"2024-08-09'T'16:09:44"}"
객체 - QA필요여부 = 통과 / QA완료시각 = 2024-08-09'T'16:09:44
장점
추가적인 컬럼을 사용하지 않아도 됨
관련 있는 필드를 JSON으로 저장되는 객체에 집약했기 때문에 응집도 높은 도메인 작성 가능
단점
DB의 데이터를 직접 열어 확인하는 경우 가독성이 좋지 않음
QA 분석 여부를 확인하기 위해서는 JSON_EXTRACT를 사용하거나 메모리에 올려서 필터링 해야함

3. 새로운 테이블 추가 + 외래키 참조(ManyToOne)

추가되는 테이블은 CandidateQaStatus라고 가정하면,
1) 외래키 nullable
상황에 따른 예시
QA가 필요없는 경우
Candidate - null
CandidateQaStatus - 레코드 없음
QA가 필요한 경우
Candidate - CandidateQaStatusId
CandidateQaStatus - QA완료시각 = null
QA가 완료된 경우
Candidate - CandidateQaStatusId
CandidateQaStatus - QA완료시각 = 2024-08-09'T'16:09:44
장점
QA가 필요 없는 경우를 Join이나 추가 쿼리 없이 null 값으로 간단하게 확인 가능
관련 필드를 하나의 테이블로 뽑아냈기 때문에 하나의 엔티티로 응집도 높은 도메인 작성 가능
추후 응시자의 QA 관련 기능이 추가 되었을 때 확장이 용이
단점
추가적인 테이블 사용
이중 null check 필요(응시자 외래키 nullable + CandidateQaStatus의 QA완료시각 nullable)
외래키 null로 인해 일관된 방식으로 처리 불가(stream 혹은 반복문에서 null check 후 로직 분기)
필요에 따라 Join 쿼리 사용해야함
2) 외래키 not null
상황에 따른 예시
QA가 필요없는 경우
CandidateQaStatus - QA필요여부 = 불필요 / QA완료시각 = null
QA가 필요한 경우
CandidateQaStatus - QA필요여부 = 필요 / QA완료시각 = null
QA가 완료된 경우
CandidateQaStatus - QA필요여부 = 통과 / QA완료시각 = 2024-08-09'T'16:09:44
장점
관련 필드를 하나의 테이블로 뽑아냈기 때문에 하나의 엔티티로 응집도 높은 도메인 작성 가능
추후 응시자의 QA 관련 기능이 추가 되었을 때 확장이 용이
단점
추가적인 테이블 사용
QA 여부를 확인하려면 항상 Join 쿼리를 사용해야함

애플케이션 및 비즈니스 특성 고려사항

QA 상태에 따른 Candidate 수
서버1
필요 3896
불필요 1344
통과 989
서버2
필요 7373
불필요 36784
통과 0
QA 상태를 나타내는 Enum 필드 추가될 가능성 없음
글 작성 시점, Enum이 필요인 응시자들만 조회와 같이 QA 여부에 따른 조회 케이스 없음
QA 상태 Enum 값을 외부에 제공하는 API 있음
응시자 엔티티가 다양하고 많은 요청에서 사용됨
QA 여부는 서버2에서는 전혀 사용되지 않음

논의 결과 및 적용

애플리케이션 특성 중 QA 상태 Enum 값을 외부에 제공하는 API 있음 -> Enum을 사용하지 않는 3-1(외래키 + nullable) 사용 불가
JSON은 부분적으로 쪼개서 사용하지 않을 단일 값만 저장하는 것이 맞음(RDB를 사용하는 이유에 반하는 행동) + 추후 필터링 조건 추가 시 많은 비용을 지불해야함(JSON 데이터를 분리하거나 성능을 포기하거나) -> JSON 방식 권장 되지 않음
프리즘에서는 해당 속성을 전혀 사용하지 않기 때문에 사용하지 않을 외부 테이블 참조 -> 추가 테이블 방식은 섣부르다
필드 추가 방식으로 결정

적용 사유

QA 여부는 응시자가 가지고 있어야할 특성이 맞음
가장 저렴한 비용으로 구현 가능
현재 시점에서는 많이 활용되지 않는 특성이고 추후 활용하는 곳이 많아진다면 그 때 테이블로 분리하는 것을 고려하는게 맞음