ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Mongo db의 embedded 관계로 설계 변경
    프로젝트/AutoMeet 2024. 5. 17. 17:52

    이번 프로젝트에서 회의 요약 보고서에 댓글을 작성할 수 있는 요구사항이 있다.

     

    처음에는 Meet collection와 Comment collection를 분리한 뒤에 comment를 저장할 때 meetId를 컬럼에 저장하는 방식으로 사용했었다.

     

    -> 생각해보니 NoSQL을 사용하며 RDBMS처럼 사용하고 있는 것이었다.

     

    mongo db의 장점은 유연한 스키마인데, mongo db의 장점을 잘 활용하지 못하고 이전에 해왔던 익숙한 방식 그대로 사용했던 것이다.

     

     

    Mongo DB의 데이터 저장 방식

    1. reference 관계

    2. embedded 관계

     

     

    1. reference 관계

    - RDBMS처럼, 위에서 내가 했다고 언급했던 것처럼 하는 것이다.

     

    문서 간의 관계 ID를 통해 참조하는 방식이다.

    장점 : 데이터 중복을 줄일 수 있다.

    단점 : 여러 번의 조회가 필요한 상황에는 쿼리가 여러번 나가서 성능이 감소할 수 있다.

     

     

    2.  embedded 관계

     - Meet의 data에 comment까지 넣는 것이다.

     

    한 문서 내에 관련된 데이터를 포함한다.

    장점 : 한 번의 조회로 필요한 모든 데이터를 가져올 수 있어서 읽기 성능이 크게 향상된다.

    단점 : 문서 크기가 커질 수 있으며, 중복 데이터가 발생할 수 있다.

     

     

    Mongo DB를 선택한 이유는 RDBMS의 제한된 스키마를 벗어나서 성능 향상을 하고 싶었던 것이므로, Mongo DB를 잘 파악하고 장단점을 잘 살리는 것이 중요하다.

     

     

     

    내가 정한 방식

    기본적으로 서비스의 사용자들이 회의를 엄청 빈번하게 하는 것이 아니기 때문에 Meet라는 데이터가 매우 많이 생성되지는 않을 것이라고 생각한다. 또한, 댓글같은 경우도 팀 회의이기 때문에 신중하게 작성할 것이며 수정, 삭제, 입력보다 read가 훨씬 많을 것이라고 생각되었기 때문에 embedded 방식을 택했다.

     

     

     

    기존의 Meet collection - comment와 분리

    @Document(collection = "meet")
    @Getter
    public class Meet {
    
        @Id
        private String _id;
        private String title;
        private String content;
        private List<Long> userIds;
    
        private LocalDateTime finishedTime;
    }

     

     

    변경된 Meet collection - comment를 내장

    @Document(collection = "meet")
    @Getter
    public class Meet {
    
        @Id
        private String _id;
        private String title;
        private String content;
        private List<Long> userIds;
    
        private List<Comment> comments; // embedded 관계
    
        private LocalDateTime finishedTime;
    
        @Builder
        public Meet(String title, String content, List<Long> userIds, LocalDateTime finishedTime) {
            this.title = title;
            this.content = content;
            this.userIds = userIds;
            this.finishedTime = finishedTime;
        }
    
        public void addComment(Comment comment) {
            if (this.comments == null) { // comments가 하나도 없으면 ArrayList를 생성
                this.comments = new ArrayList<>();
                comments.add(comment);
            }
            else { // 원래 있으면 그냥 추가
                comments.add(comment);
            }
        }
    }

     

     

     

    Meet 조회 예시

    실제 프로젝트에서 사용하는건 아니고, 연습삼아서 meet를 만들고 조회를 해봤다. 이렇게 comments가 내장된 것을 보면 쿼리 한 번으로 원하는 데이터를 가져올 수 있을 것이므로 조회 성능이 향상될 것이다.

     

     

     

    느낀점

    무작정 기술을 사용하는 것이 아니라 그 기술을 이해한 다음에 장단점을 잘 살리는 것이 가장 중요하다는 생각이 들었다.

    또한, 여러가지 기술적 choice들 중에서 내 프로젝트에 어떤 것이 적합한지 판단해서 타당한 근거를 바탕으로 최적의 설계를 하는 것이 매우 중요하기에 설계를 하는데 초점을 맞춰서 실력을 키워야겠다는 생각이 들었다.

Designed by Tistory.