애플리케이션 설계
가. 정규화(참조) vs 비정규화(내장)
•
MongoDB 스키마를 설계할 때, 가장 큰 틀에서 결정해야 할 것은 정규화(참조) 여부에 대한 것입니다. 일반적으로 정규화(참조)를 하면 쓰기 성능이 향상되고, 비정규화(내장)를 하면 읽기 성능이 향상됩니다. 왜냐하면 MongoDB의 갱신과 조회의 단위는 Document이기 때문입니다.
•
필요에 따라 참조와 내장을 혼합한 확장 참조(Extended Reference) 방식을 채택할 수 있습니다. 하나의 Document에 다른 Document에 대한 참조를 걸어두지만 함께 조회되는 데이터를 내장하고 상세 정보에 대한 조회에 대해서만 참조된 Document에서 관리하는 형태입니다.
{
"_id" : Objectld("512512a5d86041c7dca81914"),
"name" : "John Doe",
"classes" : [
{
"_id" : ObjectId("512512ced86041c7dca81916"),
"class" : "Trigonometry"
},
{
"_id" : Objectld("512512dcd86041c7dca81917"),
"class" : "Physics"
}
]
}
JSON
복사
나. 갱신과 생성 그리고 정규화
•
정기적으로 갱신해야 한다면 정규화해야 합니다. 중복이 허용된 데이터, 파편화된 데이터에 대해 일관성 있게 갱신하는 비용과 위험이 높기 때문입니다.
•
구현 후 드물게 갱신된다면 비정규화하여 읽기 성능을 향상사키는 것을 바람직합니다. 드물게 갱신된다면 정규화에 따라 쓰기 성능의 이점을 거의 누리지 못하기 때문입니다.
•
제한 없이 생성되는 데이터는 비정규화되어야 합니다. Document의 크기 제한을 고려할 때, 제한 없이 생성되는 데이터는 추후 문제가 될 수 있습니다.
다. 1:N 관계의 정규화와 비정규화
•
반대로 많다면 정규화(참조)합니다. 역시 Document의 크기 제한이슈 때문입니다.
•
N에 해당하는 엔티티가 적다면 비정규화(내장)합니다.
라. 과거 데이터 제거
•
제한 컬렉션: 컬렉션의 크기를 제한하고 최신 데이터를 앞에 배치함으로써 과거 데이터가 자동으로 제거되도록 구현합니다. 구현이 가장 쉽지만 급격한 트래픽 발생 시 컬렉션의 크기를 유지하는데 성능 이슈가 발생할 수 있습니다.
•
TTL 컬렉션: TTL 인덱스를 설정하여 지정된 시간이 지난 데이터를 삭제하도록 구현합니다. 쓰기가 많은 컬렉션에 사용하면 삭제와 쓰기의 빈번한 발생으로 인해 성능 이슈가 발생할 수 있습니다.
•
복수 컬렉션 삭제: 월별로 컬렉션을 구분하여 데이터를 관리합니다. 구축이 번거롭지만 대용량 데이터에 대해 적용하기 적절한 방법입니다.
참고
•
MongoDB 완벽 가이드 3E, 크리스티나 초도로, 새넌 브래드쇼, 오언 브라질