Entity 객체 → JPA → SQL 생성 → RDB 저장
객체 → 그대로 Document(JSON) → MongoDB 저장
예:
users
comments
comment_likes
article_views
→ 조회 시 JOIN 필요
예:
{
userId: "...",
recentComments: [...],
commentLikes: [...],
articleViews: [...]
}
→ 조회 시 한 번에 가져옴 (JOIN 없음)
SELECT ...
FROM comments
ORDER BY created_at DESC
LIMIT 10
→ 매번 계산
recentComments 리스트에 항상 10개 유지
→ 조회 시 계산 없음 (바로 응답 가능)
즉:
RDB = Write 모델 (정확한 데이터)
MongoDB = Read 모델 (빠른 조회)
UserActivityDto → API 응답용UserActivityDocument → MongoDB 저장용둘은 역할이 완전히 다르다.
겉보기에는 구조가 거의 같지만, 재사용하면 문제가 생긴다.
예:
articleTitle → title
→ DTO 변경인데 Mongo 구조까지 깨짐
Mongo에는 이런 필드가 필요할 수 있음:
updatedAt
deleted
sortKey
→ DTO에는 필요 없음
DTO에는 이런 필드가 있을 수 있음:
likedByMe
→ Mongo에는 저장 안 할 수도 있음
DTO ≠ Document
MongoDB Document 내부에는 "하위 객체"가 필요하다.
예:
UserActivityDocument
└ CommentItem
└ SubscriptionItem
└ ArticleViewItem
이 Item은:
댓글 작성 / 좋아요 / 조회
→ UserActivityUpdateService
→ Document 내부 Item 추가
→ MongoDB 저장
MongoDB 조회
→ UserActivityDocument
→ DTO 변환
→ 클라이언트 응답
이 프로젝트에서는 의도적으로 비슷하다.
이유:
즉:
MongoDB = "API 응답 미리 만들어둔 상태"
MongoDB Document 필드에서 final을 쓰지 않는 이유:
활동 내역은 이런 식으로 갱신 가능:
기존 리스트 → 새 리스트로 교체
final이면 불가능
final List<CommentItem>
→ 리스트 내부는 여전히 변경 가능
Document 필드에는 final 사용하지 않는 것이 안전
겉으로는 JSON처럼 보이지만:
{ "id": "...", "comments": [] }
실제로는:
Binary 형태로 저장
JPA
- 관계형
- SQL 기반
- JOIN 사용
- 원본 데이터 저장
MongoDB
- 문서형
- JSON 기반
- JOIN 없음
- 조회 최적화용
[ RDB ]
User / Comment / Like / Article
↓
(이벤트 발생)
↓
[ MongoDB ]
UserActivityDocument (스냅샷)
↓
[ API ]
UserActivityDto 응답