MongoDB 확장 JSON (Extended JSON)

  • 내부적으로 BSON의 일부 타입을 지원하기 때문에 mongo에서 생성된 JSON 도큐먼트를 다른 도구들이 인식하지 못하는 경우 발생
    • mongo의 JSON을 STRICT 모드와 mongo shell 모드로 구분하여 사용할 수 있다
  • STRICT 모드는 mongo 도구뿐만 아니라 외부의 모든 JSON 도구들이 JSON 도큐먼트를 파싱할 수 있다
    • 하지만 Binary, ObjectId와 같은 타입은 인식하지 못한다.
  • mongo shell 모드의 JSON 표기법을 사용하면 예외 발생

모델링 고려 사항

도큐먼트 크기

  • 일반적으로 도큐먼트는 RDB의 레코드의 크기보다 큰 경우가 많다.
    • Document DB 특성 상 하나의 도큐먼트의 여러 데이터를 모아 저장하는 경우가 있는 것으로 보임
  • 최대 크기 제한
    • 단일 document의 최대 크기는 16MB로 고정되어 있다.
    • 16MB를 초과하는 파일, 이미지, 대용량 로그 등의 경우 GridFS를 활용해 여러 청크로 분산 저장해야 한다.
  • 성능 및 리소스
    • 큰 document는 조회, 수정, 저장 시 더 많은 RAM과 디스크 I/O가 필요하므로 성능 저하 문제가 발생할 수 있다.
    • read/write 시 불필요한 large field까지 모두 불러오게 되어 네트워크 대역폭과 전체 시스템의 부담으로 이어진다.
    • frequently accessed document 크기가 크면 working set이 RAM을 쉽게 초과하여, 디스크 접근 빈도가 늘어나 DB 성능에 직접적인 영향을 준다.
  • 스키마 설계 Best Practice
    • 필요한 정보만 document에 포함시키고, 불필요한 필드를 최소화한다.
    • 깊은 중첩(nesting)을 피하며, embedded document(역정규화)와 referenced document(정규화) 전략을 적절하게 섞는다.
    • 대형 배열, unbounded array는 도큐먼트 크기를 빠르게 증가시키므로, 배열 내 개수를 제어하거나 분할 설계를 적용해야 한다.
    • 인덱스 대상 필드를 신중히 선정하며, 모든 필드를 인덱싱하면 오버헤드가 커진다.
    • 성장 가능성이 높은 document 구조는 사전에 분리(분할) 설계를 고려한다.
  • 기타 참고사항
    • Object.bsonsize() 등 shell 함수로 BSON 크기를 직접 체크할 수 있다.
    • 도큐먼트 크기 제한은 디버깅이나 ETL, batch 작업에서도 자주 문제가 되므로, 예상 성장 패턴까지 감안한 모델링이 필요하다.

정규화와 역정규화

  • 정규화 (Document Referencing)
    • 관계형 DB의 “정규화”와 유사하게, 관련 데이터를 별도의 컬렉션(테이블)로 분리하고 필요할 때 참조(reference)하는 방식
      • 학생과 수강과목 데이터를 각각 독립된 컬렉션에 저장하고, 학생 도큐먼트에는 각 과목의 id만 리스트 형태로 저장
    • 장점
      • 데이터 중복 최소화(변경 발생 시 하나만 수정)
      • 데이터 일관성, 무결성 보장에 유리
      • 컬렉션(테이블)의 크기를 작게 유지 가능
    • 단점
      • 데이터 조회 시 여러 컬렉션을 조합해야 하므로 join(lookup) 비용 증가
      • MongoDB는 복잡한 join이나 조인 성능이 RDB에 비해 떨어지는 편이다.
    • 권장 사례
      • 큰 서브 도큐먼트, 자주 갱신되는 데이터, 즉각적 일관성 필요, 증가량 많은 데이터, 빠른 쓰기 필요
      • 쓰기나 수정이 잦고, 일관성·데이터 크기가 큰 경우 referencing이 더 적합합니다.
  • 역정규화 (Embedding)
    • 관련 데이터를 한 도큐먼트 안에 중첩(embedded) 형태로 직접 포함시키는 방식
      • 학생 도큐먼트 내에 수강과목 정보를 배열로 직접 포함(예시: { classes: [{ class: “이산수학” }, …] }).
    • 장점
      • 조회 시 필요한 데이터가 한 번에 로드되어 읽기 성능(쿼리 효율)이 좋음
      • 데이터 구조가 간단해져 복합 쿼리를 줄일 수 있음
      • join이 필요없는 구조이므로 빠른 read에 최적화
    • 단점
      • 데이터 중복 증가(같은 정보가 여러 문서에 있음)
      • 일관성 관리가 어렵고, 데이터 갱신 시 여러 문서를 동시 수정 필요
      • 단일 도큐먼트 최대 크기(16MB) 제한에 주의 필요
    • 권장 사례
      • 작은 서브 도큐먼트, 자주 변하지 않는 데이터, 결과적 일관성 허용, 증가량 적은 데이터, 빠른 읽기 필요
      • 읽기 빈도가 높고, 데이터 변경이 적거나 크기가 작으면 embedding을 추천합니다.

서브 도큐먼트

  • 갱신 패턴과 단편화 문제
    • 도큐먼트 갱신은 항상 전체 도큐먼트 단위(atomic)로 이뤄진다.
    • 서브 도큐먼트가 빈번히 추가/삭제/변경되면, 내부적으로 단편화(fragmentation)가 심화되어 성능 저하 발생
    • 주기적 갱신이 많은 데이터는 Reference(정규화) 방식이 더 적합하다.
  • 데이터 액세스 패턴
    • 서브 도큐먼트가 항상 부모 도큐먼트와 함께 조회된다면 embedding이 이상적이다.
    • 반면, 독립 조회나 별도 join이 빈번하다면 referencing이 효율적일 수 있다.
  • 일관성과 중복
    • embedded 구조는 데이터 일관성 유지가 쉽지 않다. 부모 도큐먼트가 여러 곳에 중복 저장될 수 있으므로, 일괄 갱신이 어렵다.
    • 자주 변하지 않는 데이터, 작은 정적 데이터(코드, 속성 등)에 적합하다.
  • 배열의 크기와 관리
    • 큰 배열이나 크기가 계속 증가하는 embedded array는 도큐먼트 크기 한계에 가까워질 수 있다.
    • 배치가 필요하거나 배열이 무제한적으로 늘어날 수 있다면, 별도 컬렉션에 저장 후 referencing을 권장한다.
  • 인덱싱과 쿼리 성능
    • 서브 도큐먼트 내 필드도 인덱스 생성 가능하지만, 지나치게 깊은 중첩은 인덱스 성능에 영향을 줄 수 있다.
    • 주로 사용하는 쿼리 조건과 인덱스 구성을 미리 설계해야 한다.
    • 정리하면, 서브 도큐먼트 구조는 데이터의 라이프사이클, 크기, 변경 빈도, 접근 패턴, 일관성 요구, 쿼리의 효율성을 모두 종합적으로 고려하여 설계해야 한다.
    • 불필요한 대형 도큐먼트 생성을 피하고 유지보수와 성능 모두를 균형 있게 신경 쓰는 것이 중요