2023. 8. 4. 22:06ㆍ프로젝트/[Dotoring] 멘토링 어플리케이션
도토링 프로젝트를 진행하며 여러 아쉬웠던 점이 있었지만, 그 중 순위권 안에 드는 것은 단연코 설계할 시간이 너무나도 부족했던 것이다. 카카오 테크 캠퍼스와 동아리 프로젝트를 같이 병행하다 보니.. ++ 캡스톤까지
다 변명이야
8월 초에는 도토링의 DB 설계부터 단단히 다져볼 생각이다.
이와 관련하여 처음으로 포스팅할 주제는 엔티티 타입의 통합과 분리이다.
엔티티타입의 통합과 분리는 어떤 기준으로 하는 걸까??
‘아는 만큼 보이는 데이터베이스의 설계와 구축’이라는 책에서는 아래와 같이 말한다.
엔티티타입의 통합과 분리는 단순하게 엔티티타입의 모습만을 보고 결정하는 것이 아니라 분석의 대상이 되는 업무 패턴을 이해한 후에 업무의 트랜잭션의 패턴을 분석한 후에 엔티티의 통합과 분리를 결정하여라!
도토링 프로젝트의 엔티티를 설계하는 과정을 통해 엔티티의 통합과 분리에 대해서 이야기 하도록 하겠습니다!
현재 상황 분석 및 개선
현재 도토링 프로젝트의 멤버 테이블은 아래와 같습니다.
위 엔티티는 '싱글 테이블(Member)' 전략을 사용하고 있습니다. 즉, 멘토 테이블에서 구분 컬럼을 사용해 멘토와 멘티를 구분하고 있습니다.
하지만, 개발을 완료하고 나니 아래와 같은 의문이 들었습니다.
왜?? 멘토와 멘티를 통합해야하는 거지??
처음에 설계할 당시의 생각은 아래와 같았습니다.
- Mento 객체와 Menti 객체를 구성하는 속성에는 분명 공통된 것이 많이 존재한다.
- 공통된 것들을 Member 객체를 만들고, 이를 Mento와 Menti가 상속해 이를 관리한다.
- 조회 성능을 생각해 싱글 테이블 전략을 사용하자!
아주 어리석었어…
본인이 생각하기에 초기 설계의 가장 큰 문제점은 데이터베이스의 테이블 설계와 객체 설계는 아예 다른 이야기인 데 이를 분리해서 생각하지 못 했다는 것과 설계의 순서(객체 → 테이블)이다.
그리고 무엇보다 싱글 테이블 전략이 일반적으로 조회 성능이 좋은 것은 사실이지만 이번의 경우에는 트랜잭션이 한 곳으로 집중되어 오히려 성능이 저하될 수도 있다는 사실을 놓치고 있었다.
이를 개선하기 위해서는 어떻게 해야할까??
먼저, 멤버 엔티티에는 어떤 트랜잭션이 발생하고 있는 지부터 알아보자!
현재 발생하는 트랜잭션은 아래와 같다.
- 멘토 상세 조회
- 프로필 이미지, 닉네임, 직무, 학과, 소개, 소속, 연차, 멘토링 방식
- 멘티 상세 조회
- 프로필 이미지, 닉네임, 직무, 학과, 소개, 학교, 학년, 멘토링 방식
- Where절에 Job또는 Major 또는 둘을 동시에 활용한 멘토 조회
- 프로필 이미지, 닉네임, 직무, 학과, 소개
- Where절에 Job또는 Major 또는 둘을 동시에 활용한 멘티 조회
- 프로필 이미지, 닉네임, 직무, 학과, 소개
- 멘토 수정
- 직무, 학과, 소개, 소속, 연차 수정
- 멘토링 방식 수정
- 계정 설정
- 멘티 수정
- 직무, 학과, 소개, 학교, 학년 수정
- 멘토링 방식 수정
- 계정 설정
현재 사용되는 쿼리들을 살펴보니 멘토와 멘티를 동시 조회하여 사용하는 쿼리는 없다.
또한, 3번과 4번은 어플 홈화면을 들어가면 무조건 사용되는 쿼리들이고 1번과 2번 또한 멘토와 멘티에 대해서 확인해볼 때 사용하는 쿼리이므로 사용빈도가 매우 높다.
위와 같은 것들을 종합해서 생각해보니 Member 엔티티안에 Mento와 Menti를 구분 컬럼을 구분해 하나의 엔티티에 담을 필요가 없었다.
중간 결론은 다음과 같다.
Member 엔티티를 Mento 엔티티와 Menti 엔티티로 분리!!
⇒ 이를 통해 배운 점은 테이블 설계를 먼저 한 뒤에 객체를 설계해야 한다는 것이다.
만약 앱을 출시한다면, 사용되는 트랜잭션의 빈도는 아래와 같은 것이다.
- 멘토/멘티 조회(홈 화면)
- 멘토/멘티 상세 조회
- 멘토/멘티 수정 - a,b
- 멘토/멘티 수정 - c
1, 2, 3번에의해서 아래와 같이 엔티티를 설계할 수 있다.
멘토 - 닉네임, 직무, 학과, 소개, 소속, 연차, 멘토링 방식, 상태
멘티 - 닉네임, 직무, 학과, 소개, 학교, 학년, 멘토링 방식, 상태
여기서 고민해야할 점은 아이디, 비밀번호, 이메일을 따로 엔티티로 분리할 것인가 아니면 합칠 것인가이다.
멘토를 기준으로 발생하는 쿼리들을 살펴보면..
- 아이디, 비밀번호, 이메일, 권한을 사용하여 프로필 이미지, 닉네임, 직무, 학과, 소개, 소속, 연차, 멘토링 방식, 상태를 조회하거나 수정하는 일이 아직까지는 없다.
- 회원에 대한 계정 관련 정보들은 그들만을 사용해 서로를 찾고 수정한다.
따라서, 엔티티를 아래와 같이 분리하고자 한다.
- 멘토 엔티티 : 닉네임, 직무, 학과, 소개, 소속, 연차, 멘토링 방식, 상태
- 멘티 엔티티 : 닉네임, 직무, 학과, 소개, 학교, 학년, 멘토링 방식, 상태
- 멘토 계정 엔티티 : 아이디, 비밀번호, 이메일, 권한
- 멘티 계정 엔티티 : 아이디, 비밀번호, 이메일, 권한
기획의 추가된 요구사항에 따라 멘토와 멘티는 각각 복수의 직무와 학과를 가질 수 있다.
따라서 최종적으로 아래와 같은 엔티티가 만들어진다.
- 멘토 엔티티 : 닉네임, 소개, 소속, 연차, 멘토링 방식, 상태
- 멘티 엔티티 : 닉네임, 소개, 학교, 학년, 멘토링 방식, 상태
- 멘토 계정 엔티티 : 아이디, 비밀번호, 이메일, 권한
- 멘티 계정 엔티티 : 아이디, 비밀번호, 이메일, 권한
- 직무 엔티티
- 학과 엔티티
다음으로, 증명서/이미지 엔티티입니다.
회원의 증명서 같은 경우에는 중요한 개인정보이기도 하고, 관리자 페이지에서만 확인할 수 있습니다.(조회 상황 한정)
또한, 홈화면에서 멘토, 멘티의 프로필 이미지를 계속 보여주니 이미지 테이블을 증명서 테이블과 분리하는 것이 좋다고 판단했습니다.
- 증명서 엔티티 : 원본 파일 명, 저장시 사용할 파일 명, 업데이트 일자, 삭제 일자, 삭제 상태
- 이미지 엔티티 : 원본 이미지 명, 저장시 사용할 이미지 명
따라서, 최종으로 만들어진 엔티티는 아래와 같습니다!
- 멘토 - 닉네임, 소개, 소속, 연차, 멘토링 방식
- 멘토 계정 - 멘토 아이디, 멘토 비밀번호, 멘토 이메일
- 멘티 - 닉네임, 소개, 학교, 학년, 선호 멘토링
- 멘티 계정 - 멘티 아이디, 멘티 비밀번호, 멘티 이메일
- 증명서 - 원본 파일 명, 저장시 사용할 파일 명, 생성 일자, 삭제 일자, 삭제 상태
- 프로필 이미지 - 원본 이미지 명, 저장시 사용할 이미지 명
- 학과
- 직무
검증
트랜잭션을 기준으로 엔티티를 나눠본 후에 아래 항목을 바탕으로 만들어진 엔티티를 검증해보자!!
- 유연성 : 분리되어 있을 때와 통합되어 있을 때 어느 때가 관계를 더 정확히 판단할 수 있는 지!
- 필자는 만족했다고 생각!
- 업무 이해도
- 필자는 만족했다고 생각!
- 복잡도
- 기존의 엔티티보다 복잡…
- 유지보수성
- 기존의 엔티티보다 낫다고 할 수 있지 않을까…??
- 데이터 량
- 사실상 이 부분은 실제 앱 사용자가 매우 많다고 가정하고 엔티티를 만들 것이다! - 타협 불가
- 필자는 사람이 많이 사용하는 앱을 운영하는 회사를 가고싶기 때문이다.
이상입니다!!
다음 주제입니다!!
https://rasony.tistory.com/157
'프로젝트 > [Dotoring] 멘토링 어플리케이션' 카테고리의 다른 글
QueryDSL을 사용해 통계(Count)쿼리의 결과를 사용해서 정렬하기 (0) | 2023.08.15 |
---|---|
데이터 무결성 지켜야지, 안 지킬거야?? (0) | 2023.08.07 |
식별자, 비식별자 관계는 뭐고 언제 사용해야하는 걸까?? (0) | 2023.08.04 |
읽기 전용 쿼리의 성능 최적화에 대한 고민 (0) | 2023.07.31 |
메서드가 연속으로 실행된다면, 트랜잭션이 중첩되어 데이터가 저장되지 않고 계속 수정되는 거 아냐?? (0) | 2023.07.26 |