<aside> 💡 목차
</aside>
채팅 메시지의 경우 많은 접근과 많은 데이터가 관리될 것으로 예상되기에 MySQL DB가 아닌 Mongo DB를 사용하여 구현하게 되었다.
효율적으로 DB를 접근하기 위해서 인덱싱이 필요한데, NoSQL인 Mongo DB에서도 인덱싱을 구현할 수 있었다.
<aside> ❓ 으으음 메시지를 구분할 수 있는 MessageId에만 인덱싱을 걸면 되는거 아냐?
</aside>
음, 확실히 MessageId만으로도 인덱싱의 이점이 있을 수 있다. 틀린말은 아니다. 하지만 조금 더 요구사항과 데이터베이스 접근에 대해 고민해본다면 좋은 결과를 만들 수 있다.
MongoDB에서는 인덱싱 전략을 효율적으로 구성하기 위해 ESR 룰이 존재한다.
The ESR (Equality, Sort, Range) Rule
간단히 요약하자면 다음과 같다
<aside> 💡 ESR Rule: 어떤 document fields에 인덱싱을 걸어야할까?
를 우선으로 인덱싱을 건다.
</aside>
그렇다면 프로젝트의 트랜잭션들을 살펴보자
<aside> ⏩ 채팅 메시지 Document 접근하는 경우는 다음과 같다.
채팅 메시지 조회(Read)
db.messages.find({ chatRoomId: "<채팅방ID>" })
.sort({ timestamp: -1 })
.limit(100);
채팅 요약 정보 조회(Read)
// 최신 메시지 조회
db.messages.find({ chatRoomId: "<채팅방ID>" })
.sort({ timestamp: -1 })
.limit(1);
// 읽지 않은 메시지 수 조회
db.messages.countDocuments({ chatRoomId: "<채팅방ID>", read: false });
채팅 메시지 저장(Create)
채팅 메시지 읽음 처리(Read, Update)
db.messages.updateMany(
{ chatRoomId: "<채팅방ID>", read: false },
{ $set: { read: true } }
);
</aside>
빨간 색 글씨 부분에서 인덱싱이 필요한 필드를 유추해볼 수 있다.
따라서
프로젝트에서 자주 사용될 작업을 생각한다면 RoomId 와 MessageId(혹은 timeStamp) 모두 복합 인덱스로 만들어줄 필요가 있어보인다.
트랜잭션을 살펴본다면 읽지 않은 메시지(isRead가 false인 메시지)를 찾는 경우가 있다.