mongoDB 불필요 쿼리 제거
< 문제상황 >
자신이 찍은 사진을 공유하고 댓글을 남길 수 있는 서비스를 개발중에, 게시글의 댓글을 불러올 때 불필요하게 많은 쿼리들이 데이터베이스(mongoDB)에 요청이 되어서 로딩 시간이 길어짐.
< 유저와 댓글 도큐먼트>
User | Comment | ||
_id | <ObjectId0> | _id | <ObjectId1> |
"test@test.com" | author | <ObjectId0> | |
nickname | "Lee" | description | "beautiful image!" |
password | "encrypted" | createdAt | "2022-04-04T05:03:00.293Z" |
: 댓글을 렌더링하기 위해서는
1. 작성자의 닉네임,
2. 댓글의 내용
총 두가지가 필요한데 현재 댓글 도큐먼트에 작성자의 닉네임은 없고 작성자의 id만 있기 때문에 서버에 해당 유저의 정보를 불러온 다음 닉네임을 추출해 렌더링 해야하는 문제가 발생했다.
이렇게 되면 총 10개의 댓글이 있다고 가정했을 때, 총 11번의 데이터 요청(쿼리)[댓글 요청 1번 + 각 댓글별 유저 정보 요청 10번]가 필요하기 때문에 작업에 비해 쿼리의 수가 너무 많다고 생각했고, 로딩 속도도 너무 느렸다.
< 접근1 >
mySQL이나 postgreSQL같이 관계형 데이터베이스 였으면 이렇게 하는 게 맞겠지만, mongoDB는 도큐먼트별로 중복되는 값이 있더라도 한번의 쿼리로 많은 데이터를 받아와 적절히 사용할 수 있는 게 장점이라고 생각했다.
그래서 도큐먼트를 올바르게 수정하기 위해 mongoDB스키마 작성법을 찾아보았다.
참고한 Reference:
이 영상이 많은 도움이 되었는데, 정리해보자면
- 규칙 1. 삽입하지 않을 이유가 없는 한 도큐먼트에 값을 넣어라
- 규칙 2. 피할 수 있다면 JOIN 쿼리를 피해라
- 규칙 3. 배열은 경계없이 커지면 안된다(one to many 관계에서)
- 규칙 4. 객체를 개별적으로 액세스해야하는 경우, 해당 객체는 삽입하지 마라
규칙 1에 따라서, 현재 댓글 조회시 작성자의 닉네임도 필요하기 때문에 댓글 도큐먼트(스키마)에 작성자의 닉네임 값도 추가해주었다
Comment | |
_id | <ObjectId1> |
author | <ObjectId0> |
nickname | "Lee" |
description | "beautiful image!" |
createdAt | "2022-04-04T05:03:00.293Z" |
댓글 뿐만 아니라, 게시글 조회시에도 게시글의 작성자 닉네임이 없어 불필요한 쿼리들이 데이터베이스에 요청하는 것을 파악했고, 게시글 도큐먼트(스키마)에도 닉네임 필드를 추가해주었다.
이를 통해 댓글 또는 게시글 조회시 필요한 쿼리수를 댓글(게시글) 수 만큼 줄일 수 있었다.
기존의 쿼리 수 : 댓글(게시글) 갯수 + 1
변경 후 쿼리 수 : 1
< 해결 과정 >
1. mongoDB 스키마 작성 규칙 파악
2. 도큐먼트에 필요값 필드 추가