연결된 포스팅이다 이전 글을 참고하라.
- 스키마 설계 고려 사항
- 데이터 embed 방식과 참조 방식 중 결정하기 - (현재지점)
- 최적화를 위한 팁
- 일관성 고려 사항
- 스키마 마이그레이션 방법
- 스키마 관리 방법
- 몽고 DB가 데이터 스토리지로 적합하지 않은경우
정규화 및 비정규화
정규화 : 각 컬렉션 간의 참조를 이용해 여러 컬렉션으로 나누는 작업
비정규화 : 모든 데이터를 하나의 도큐먼트에 내장
비 정규화는 정보가 갱신되면 여러 도큐먼트가 갱신되야하지만, 하나의 쿼리로 모든 데이터를 가져올 수 있음을 뜻한다.
따라서 정규화는 RDBMS를 설계하는 방법과 매우 유사하며,
비정규화는 MongoDB의 특색을 잘 표현한다.
아래는 정규화스러운 데이터 표현 예제이다.
db.studentClasses.findOne({"studentId" : id})
{
"_id" : ObjectId("512512c1d86041c7dca81915),
"studentId" : ObjectId("512512c1d86041c7dca81105),
"classes : [
ObjectId("512512c1d86041c7dca81916),
ObjectId("512512c1d86041c7dca81917),
ObjectId("512512c1d86041c7dca81918),
ObjectId("512512c1d86041c7dca81919)
]
}
Classes에서 각 데이터를 가지고 있는것이 아닌, 다른 class라는 도큐먼트를 참고하고 있는 형태이다.
하지만 이는 한번의 데이터를 얻을 때 여러번 쿼리해야하기 때문에
일반적으로는 위와 같이 저장하지 않는다.
해당 정보를 아예 classes 내에서 보관한다.
아래는 보다 MongoDB 스러운 비정규화한 도큐먼트 구조이다.
db.studentClasses.findOne({"studentId" : id})
{
"_id" : ObjectId("512512c1d86041c7dca81915),
"name" : "John Doe",
"classes : [
{
"class" : "Math",
"credits" : 3,
"room" : "204"
},
{
"class" : "History",
"credits" : 3,
"room" : "159"
},
{
"class" : "English",
"credits" : 3,
"room" : "14b"
},
{
"class" : "Physics",
"credits" : 3,
"room" : "321"
}
]
}
위 처럼 저장하면 쿼리를 하나만 사용하여 모든 정보를 얻을 수 있지만,
더 많은 공간을 차지하고 동기화가 어렵다는 단점이 있다.
물리학이 3학점이 아닌 4학점이라면 위 예시의 도큐먼트를 수정하는 것이 아닌,
모든 학생의 도큐먼트를 수정해야할 일이 발생하는 것이다.
여기서 확장 참조 패턴을 사용하면 아래와 같이 바꿀 수 있다.
db.studentClasses.findOne({"studentId" : id})
{
"_id" : ObjectId("512512c1d86041c7dca81915),
"name" : "John Doe",
"classes : [
{
"_id" : ObjectId("512512c1d86041c7dca81916),
"class" : "Math"
},
{
"_id" : ObjectId("512512c1d86041c7dca81917),
"class" : "History"
},
{
"_id" : ObjectId("512512c1d86041c7dca81918),
"class" : "English"
},
{
"_id" : ObjectId("512512c1d86041c7dca81920),
"class" : "Physics"
}
]
}
장점이 보이는가?
이를 정리하고, 몇가지 예시를 들어본다.
내장 방식이 좋은 경우 | 참조 방식이 좋은 경우 |
작은 서브도큐먼트 | 큰 서브도큐먼트 |
주기적으로 변하지 않는 데이터 | 자주 변하는 데이터 |
결과적인 일관성이 허용될 때 | 즉각적인 일관성이 필요할 때 |
증가량이 적은 도큐먼트 | 증가량이 많은 도큐먼트 |
두 번째 쿼리를 수행하는데 자주 필요한 데이터 | 결과에서 자주 제외되는 데이터 |
빠른 읽기 | 빠른 쓰기 |
users 컬렉션이 존재할 때 아래와 같을 것이다.
계정 설정 - 내장
최근 활동 - 크기가 최근 10개 활동 처럼 고정된 경우 내장이 좋을 것 임
친구 - 내장하지 않는다.
사용자가 생성한 모든 내용 - 내장하지 않는다.
다음장 바로가기
https://inventer.tistory.com/31
'Infra > MongoDB' 카테고리의 다른 글
MongoDB - (11) - 애플리케이션 설계(4) (0) | 2023.04.24 |
---|---|
MongoDB - (9) - 애플리케이션 설계(2) (0) | 2023.04.22 |
MongoDB - (9) - 애플리케이션 설계 (0) | 2023.04.22 |
MongoDB - (8) - 트랜잭션 (0) | 2023.04.22 |
MongoDB - (7) - 집계 프레임워크 (0) | 2023.04.22 |
댓글