프로젝트/AutoMeet

Mongo db의 embedded 관계로 설계 변경

chanhee01 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들 중에서 내 프로젝트에 어떤 것이 적합한지 판단해서 타당한 근거를 바탕으로 최적의 설계를 하는 것이 매우 중요하기에 설계를 하는데 초점을 맞춰서 실력을 키워야겠다는 생각이 들었다.