본문 바로가기
개발 공부/DataBase

[MongoDB] MongoDB 용어 정리 + 설계 방법

by sngynhy 2022. 2. 17.
SQL MongoDB
Database Database
table collection
row document or BSON document
column field
index index
primary key _id (MongoDB에서는 primary key와 같은 역할의_id값이 자동으로 부여됨)
DB Server mongod
DB Client mongo

참고)

https://ryu-e.tistory.com/2

https://7stocks.tistory.com/10

 

설계

데이터 모델링? 업무 수행 시 발생하는 데이터를 정확하고 효율적으로 DB에 저장하기 위해
데이터 구조를 설계하는 과정을 의미

mongoDB 데이터 모델링
도큐먼트 구조 설계 -> 컬렉션 설계

도큐먼트 구조?
도큐먼트는 RDB의 행(row)와 같은 개념
데이터를 저장하는 최소 단위
 1. 임베디드 방식 (중첩)
 2. 레퍼런스 방식 - 자식 참조 / 부모 참조 / 상호 참조

1. 임베디드 방식
관계를 갖는 데이터 집합을 단일 도큐먼트에 포함(중첩)하여 저장하는 방식
- 임베디드 방식은 동일한 데이터를 하나의 도큐먼트에 저장하여 구조를 단순화하는 반정규화 모델
- 조회 성능이 뛰어나고 도큐먼트에 포함된 관련 데이터를 모두 업데이트 가능
- 데이터 관리가 직관적이고 쿼리가 단순함
- 데이터가 중복될 수 있기 때문에 데이터 불일치 발생 가능
- 한 도큐먼트가 포함하는 데이터의 양이 증가할수록 도큐먼트의 크기도 증가하여
I/O 시 성능 저하 발생 및 도큐먼트의 최대 크기를 초과 시 저장 불가능
- 데이터의 관계가 복잡하거나 계층 구조를 갖는 업무의 경우 관리가 어려움
- 권장 업무 : 조회 성능이 중요하고 데이터 중복에 따른 불일치가 문제 없는 경우
업데이트가 과도하게 발생하지 않는 경우

2-1. 레퍼런스 방식 (기본)
도큐먼트에 관계를 갖는 다른 도큐먼트의 식별자를 참조키로 저장하여 필요 시 참조하는 방식
- 데이터가 중복되지 않도록 업무 성격별로 컬렉션을 분리 후 참조하므로 데이터 불일치가 발생하지 않는 정규화 모델링
- 적절한 업무 단위의 컬렉션으로 데이터가 분리되어 임베디드 방식 대비 도큐먼트의 크기가 작음
- 업무 요건 추가 및 변경으로 인한 도큐먼트 구조에 미치는 영량이 적음
- 참조가 많은 도큐먼트 또는 대규모 도큐먼트를 조회하는 경우 애플리케이션에서 2차 쿼리로 인한
처리량 증가로 조회 성능 저하
- 데이터 중복에 의한 데이터 일관성 문제는 해소되나, 참조 정보를 정확하게 관리하지 않는 경우
참조 정보 소실에 의한 데이터 정합성 문제 발생
- 권장 업무 : 조회 성능보다는 데이터 무결성이 중요한 업무, 디스크 I/O 성능에 문제가 예상되는 경우,
데이터의 관계가 복잡하거나 계층 구조를 갖는 업무

2-2. 레퍼런스 방식 (세부)
세부 레퍼런스 방식은 관계를 갖는 도큐먼트들 중 참조키를 어떤 도큐먼트에 저장할 것인지에 따라
다음의 3가지 참조 방식으로 나뉨
1. 자식 참조 (부모가 자식을 참조)
- 부모 doc에서 관계를 갖는 자식 doc의 식별자(_id)를 참조키로 저장하는 방식
- 부모 doc과 관계를 갖는 자식 doc을 쉽게 찾을 수 있으며 참조 정보가 부모 doc에만 존재하므로 관리 용이
- 부모 doc에 업데이트가 집중되어 성능 문제가 발생할 수 있으며 자식 doc이 많은 경우 doc의 최대 크기 초과
- 부모 doc에 발생하는 부하 및 크기 증가를 고려하여 자식 doc이 적게 생성되는 업무에 적합
2. 부모 잠조 (자식이 부모를 참조)
- 자식 doc에서 관계를 갖는 부모 doc의 식별자를 참조키로 저장하는 방식
- 자식 doc에서 부모 doc를 쉽게 찾을 수 있으며 자식 doc의 추가 및 삭제로 인한 부모 doc의 업데이트가 없음
- 부모 doc과 관계를 갖는 모든 자식 doc 조회 시 소요시간 증가
- 이력 또는 로그 데이터와 같이 자식 doc가 많이 생성되는 업무에 적합
3. 상호 참조
- 관계를 갖는 부모 doc과 자식 doc이 각각 서로의 식별자를 참조키로 저장하는 방식
- 상호적으로 찾기가 쉬우나 참조 정보 관리의 어려움 존재
- 부모 doc과 자식 doc 모두 업데이트가 과도하게 발생할 수 있으며,
참조 정보 관리 부주의 시 데이터 정합성 문제가 쉽게 발생
- 데이터 변경이 적고 부모 doc과 자식 doc이 서로를 빈번하게 참조하는 업무에 적합


컬렉션?
RDB의 테이블(table)과 같은 개념
용도가 같거나 유사한 도큐먼트들의 그룹을 묶는 단위를 의미
1. 일반 컬렉션
2. 캡드 컬력션
- 고정된 크기를 갖는 컬렉션 => 높은 성능의 로깅 기능을 위해 설계됨
- 명령어 : db.createCollection( "log"\, { capped : true, size : 100000, max : 100 } )
1) "log" 컬렉션 생성 시 캡드 옵션을 설정하고 최대 사이즈와 최대 도큐먼트 수를 설정함
2) size : 최대 저장크기로 단위는 Byte임
3) max : 최대 도큐먼트 수로 옵션 생략이 가능함
- 도큐먼트 추가 시 디스크 공간이 없는 경우 가장 오래전에 추가된 도큐먼트부터 덮어쓰기 함
- 오래된 데이터를 수동으로 삭제하는 작업을 없애 데이터 관리가 편리함
- 로깅을 위해 만들어져 사용자가 임의로 삭제하거나 업데이트할 수 없음
3. TTL 컬렉션
- 특정 시간이 경과한 도큐먼트를 자동으로 삭제하는 컬렉션
- TTL 인덱스에 의해 지원
- 명령어 : db.member.createIndex( { modify_date : 1 }\, { expireAfterSeconds : 3600 } )
1) modify_date 필드에 인덱스를 생성하여 1시간(3600/60/60)이 지난 도큐먼트는 삭제함
2) expireAfterSeconds : 도큐먼트의 유지시간을 초 단위로 설정함
- "_id" 필드 또는 이미 다른 인덱스가 있는 필드는 TTL 인덱스를 가질 수 없음
- 캡드 컬렉션인 경우 TTL 인덱스를 가질 수 없음
- 단일 인덱스만 사용 가능하며 복합(Compound) 인덱스를 가질 수 없음
4. 시스템 컬렉션
- mongoDB 내부에서 사용되는 컬렉션으로 사용자가 지정하여 사용 불가능

데이터 모델링 절차
요구 사항 수집 -> 업무 데이터 분석 -> 도큐먼트 설계 -> 컬렉션 설계

※참고 https://meetup.toast.com/posts/276

도큐먼트 구조
MongoDB 애플리케이션을 위한 데이터 모델을 디자인하는데 있어 주요 결정사항은
"도큐먼트의 구조와 애플리케이션이 데이터 사이의 관계를 어떻게 표현하느냐"를 중심으로 돌아간다.

 

MongoDB - Index 생성 전략

1. Selectivity (선택력) - 보다 정확하게 검색할 수 있도록 좁은 범위를 갖는 색인
2. '읽기'와 '쓰기'의 비중 파악 - 쓰기 > 읽기 인 경우 인덱스를 복잡하게 설정하게 되면 나쁜 성능을 낼 수 있음
3. 사용 가능한 메모리 크기 고려
- 인덱스는 실제 데이터와 별개의 메모리 공간에 저장하기 때문에 그만큼 메모리를 사용하게 된다.
  DB가 정상적으로 동작하기 위해서는 그 외에도 작업셋이라는 데이터 구조도 메모리를 점유하게 되기 때문에
  메모리가 부족하는 문제가 발생하지 않도록 주의 필요
  
=> 가급적 촘촘하게 인덱스를 작성해서 selectivity를 높이기
쓰기 작업이 많은 데이터셋은 인덱스를 복잡하게 설계하지 않기
메모리를 충분히 확보하고 항상 관찰하기

MongoDB는 쿼리 수행 시 어떤 방식으로 검색을 할 지 스스로 계획을 세우고, 인덱스를 활용
적합하지 않은 인덱스가 지정되었을 경우 스스로 그것을 사용하지 않음
이와 같이 불필요한 인덱스는 제거해주어야 함
이를 위해 MongoDB는 현재 수행 중인 쿼리가 어떤 계획을 세우는지, 어떤 인덱스를 사용하는지,
얼마나 오랜 시간 검색을 수행하는지 등을 보여주는 방법들을 제공
(좋은 인덱스 전략을 세우는 가장 중요한 요소는 "반복적인 테스트")
인덱스 검사를 위해 주로 사용하는 메소드 => hint(), explain()

db.products.createIndex({ fieldName: 1 }) // 1 : 오름차순, -1: 내림차순