...
MongoDB 란?
MongoDB는 문서 지향 데이터 모델(Document DB)을 사용하는 데이터베이스 이다.
이러한 유형의 모델을 사용하면 정형 및 비정형 데이터를 보다 쉽고 빠르게 통합할 수 있다는 장점이 있다.
RDBMS는 MySQL이 많이 쓰이듯이, NoSQL 데이터베이스중 대표격이라고 말할 정도로 가장 많이 쓰인다.
[NoSQL DB vs 관계형 DB 비교]
항목 | NoSQL | RDBMS |
적합업무 | - 오프라인에서 정형 및 비정형 데이터 분석 업무 - 초당 동시 처리가 중요한 업무 - 로그 및 이력 등의 단순 기록형 업무 |
- 데이터 무결성 및 일관성이 중요한 트랜잭션 업무 - 온라인에서 다양한 집계 및 통계를 분석하는 업무 - 복잡한 계산 및 실시간 데이터 정합성이 필요한 업무 |
데이터 모델 | - 서비스에 맞는 DB 선택이 중요함 - 반정 규화에 의한 설계를 기본으로 함 - 비정형화 스키마 구조로 미리 스키마를 선언하지 않음 |
- 엔티티 및 각 엔티티 간 관계를 정의함 - 엔티티 정의 시 정규화에 의한 설계가 중요함 - 테이블\, 칼럼 등 DB요소에 대한 스키마를 엄격히 관리함 |
성능 | - 클러스터 크기\, 네트워크 및 애플리케이션에 의해 성능이 결정됨 | - 성능 향상을 위해서는 성능 최적화 작업이 필요함 |
인터페이스 | - 쿼리 외 다양한 API를 통한 데이터 저장 및 검색이 가능함 | - SQL을 통해서만 데이터 저장 및 검색이 가능함 |
장점 | - 쿼리 프로세싱이 단순화되어 대용량 데이터 처리 성능이 향상됨 | - 데이터 중복 배제로 데이터 이상 발생 및 용량 증가를 최소화함 |
단점 | - 데이터 중복에 의해 데이터 일관성이 저하되고 용량이 증가함 | - 조인이 복잡한 경우 쿼리 프로세싱도 복잡해져 성능이 저하됨 |
몽고디비만의 장점과 특징은 다음과 같다. (영상을 참조하면 더 쉽게 이해가 가능하다)
MongoDB 특징
신뢰성(Reliability)
- 서버 장애에도 서버가 유동적으로 분담하여 서비스는 계속 동작 유지
- Primary 와 Secondry로 구성된 ReplicaSet 구조로 고가용성을 지원
몽고디비는 기본적으로 하나의 primary와 두개의 secondary로 ReplicaSet을 구성한다.
primary는 데이터 쓰기 요청을 처리하고,secondary는 primary부터 변경된 데이터를 복제한다.
이렇게 데이터를 복제하고 유지함으로서, 하나의 서버에서 장애가 발생하더라도 데이터를 유지할 수 있다.
만일 primary서버에 문제가 생기면, secondary가 primary로 전환되어 서버를 계속 유지시킨다.
그리고 다시 빈 secondary서버를 몽고디비가 복구 시켜줌으로서 서버를 유지할수 있게 된다.
확장성(Scalability)
- 데이터와 트래픽 증가에 따라 수평확장(scale-out) 가능
- 데이터를 샤딩하여 수평확장(scale-out) 할 수 있음
몽고DB에 데이터가 증가하여 더이상 하나의 Replica Set에 담을 수 없게 되면, 몽고DB는 데이터를 샤딩하여 분산시켜 줄 수 있음.
이러한 샤딩과정은 서비스 중단없이 온라인으로 진행된다.
만약 특정 샤드에 데이터가 몰리면 다른 샤드로 데이터를 이동 시켜, 전반적으로 모든 샤드가 균등하게 데이터를 저장할 수 있도록 해준다.
이러한 동작을 밸런싱이라고 한다.
몽고DB는 온라인상에서 데이터를 밸런싱 해줄 수 있기 때문에 단일 Replica Set 에서 샤드로의 온라인 전환이 가능하며
샤드의 확장 축소도 모두 온라인으로 진행 가능 하다.
유연성(Flexibility)
- 여러가지 형태의 데이터를 손쉽게 저장
- 서비스 요구사항에 맞춰 다양한 종류의 데이터가 추가되어도 스키마 변경 과정 없이 필요한 데이터를 바로 저장하고 읽을 수 있음
- 예를들어 날짜를 저장하고 싶은데 테이블에 날짜 관련 컬럼이 없다면 따로 필드를 추가해야 하는 테이블이 조작이 필요 하지만, 몽고디비는 그냥 써주면 알아서 인식됨.
만얀 핸드폰에 OS종류를 구분해야한다면, RDBMS에서 컬럼을 새로 추가해야 할 것이다.
그런데 RYAN이라는 사람이 또 휴대폰을 구매하면 어떻게 해야할까? 또 컬럼을 추가해야 할까?
RDBMS는 이러한 상황을 테이블을 분리하고 관계를 맺음으로서 해결한다.
하지만 몽고DB는 Schema 가 없으므로 데이터 변경에 유연하게 대처할 수 있다
몽고DB는 JSON 기반에 Document 모델을 사용하는데, Document 는 다양한 형태의 데이터를 한번에 담을 수 있으므로 여러가지 정보를 한눈에 볼 수 있게 표현해준다
또한 Application에서 다루는 오브젝트와 1:1로 매칭되기때문에 개발자는 데이터를 쉽게 이해하고 빠르게 개발할 수 있다
RDBMS는 복잡하게 테이블이 얽혀있는 것에 반해, NOSQL은 한눈에 보기 쉽도록 가독성이 높아진것을 확인 할 수 있다.
Index 지원(Index Support)
- 다양한 조건으로 빠른 데이터 검색
- 대부분 NoSQL들과 다른 몽고디비 만의 큰 차이점
- 필요한 필드에 필요한 만큼 생성 가능
- 대용량 데이터에서 다양한 조건으로 조회 가능
- 다양한 형태의 Index 를 제공
- Hashed Index (샤드 클러스터에서 데이터를 균등하게 분배하고자 할때 사용)
- Multikey Index
- Partial Index
- TTL Index (제한시간을 설정하여 오래된 데이터를 자동으로 지워주는 인덱스)
- Geospatial Index (공간인덱스) 공간내에 거리나 범위를 계산 카카오 택시, 카카오 대리, 카카오 모빌리티
몽고디비 데이터 모델링
- Database :
Collection의 물리적 컨테이너 - Collection :
RDBMS에서의 table이라고 생각하면 된다.
Document의 그룹, Document의 내부에 위치해 있음.
RDBMS와 달리 스키마를 따로 갖고 있지 않음 (동적 스키마로 생성) - Document :
nosql을 다른말로 Document Oriented Database라 함.
한개 이상의 key-value 쌍으로 이루어진 구조
일반 rdbms에서는 row or tuple과 유사하다 생각하면 된다. - Key/Field :
일반 Rdbms에서 Column이라 생각하면 된다.
컬럼 명과 저장 값으로 생각하면 쉽다.
이들의 관계를 그림으로 표현하면 아래 이미지와 같다.
한 쌍 이상의 Key 와 value가 pair 로 이루어진 Document 들이 모여 Collection 을 이루고, Collection 들은 Database 안에 포함 되어 있다. 그리고 Database 는 Server 안에 위치한다.
MongoDB 모델 구성을 알아봤으니 직접 Document 를 모델링 해보자.
이해를 돕기위해 인스타그램을 위한 데이터베이스를 모델링한다고 가정해 본다.
인스타그램에서 게시물을 올릴 때 필요한 정보는 다음과 같다.
- 게시글에는 사진, 설명, 작성자, 작성일이 포함되어 있다.
- 게시글에는 0개 이상의 해쉬태그를 가질 수 있다.
- 게시글에 덧글을 달 수 있다.
만약 관계형 데이터베이스를 이용한다면 table 은 총 세개가 만들어 져야 할 것이다.
comment, article, hashtags 테이블들은 각각의 구조(Schema)를 가지고 있고, table 안의 row 들을 이 구조를 따라야 한다. 그리고 각 테이블의 id 의 관계성을 이용하여 세 테이블을 JOIN 시켜 한 페이지에 출력할 것이다.
위와 같은 데이터를 MongoDB 에서 처리하려면, MongoDB 는 Schema-less 이므로 하나의 Collection 하위의 Document 들이 모두 같은 구조를 가지고 있을 필요가 없다.
{
_id: POST_ID, title: POST_TITLE,
content: POST_CONTENT,
author: POST_WRITER,
hashtags: [ TAG1, TAG2, TAG3 ], // subdocument
time: POST_TIME
comments: [ // subdocument
{
username: COMMENT_WRITER,
mesage: COMMENT_MESSAGE,
time: COMMENT_TIME
},
{
username: COMMENT_WRITER,
mesage: COMMENT_MESSAGE,
time: COMMENT_TIME
}
]
}
따라서 위와 같이 하나의 Document 안에 모든 정보를 포함한다.
Document 안에 있는 hashtags, comments 의 배열과 같은 하위의 Document 를 subdocument 라고 한다.
만약 어떤 게시물에 태그나 덧글이 없다면 해당 필드가 없어도 상관없다. (Schema-less)
MongoDB에서 사용하는 JSON vs BSON
몽고DB는 Document로 데이터를 관리하고 있다.
이때 우리 눈으로 데이터를 받아보면 모두 JSON형태로 데이터를 보여주고, 저장한다. 또 검색기능을 사용할 때에도 JSON문법에 맞게 입력해준다.
하지만 정확히 몽고DB에서는 데이터를 BSON형태로 저장하여 사용하고 있다.
JSON 형식
일반적으로 JSON은 JavaScript Object Notation의 줄임말로 Javascript 언어의 일부로 정의되어있는 형식이며 2013년에 공식화 된 형식이다.
JSON의 형태는 일반적으로 key와 value의 값으로 채워져 있다.
직관적이고 간단한 특성으로 쉽게 이해할 수 있는 형태의 표현 방법이다.
{
"_id": "10009999",
"listing_url": "https://www.aaabbb.com/rooms/10009999",
"name": "Horto flat with small garden",
"summary": "One bedroom + sofa-bed ...",
"cancellation_policy": "flexible",
"last_scraped": {
"$date": {
"$numberLong": "1549861200000"
}
}
}
BSON 형식
BSON은 단순히 말하면 Binary JSON이다.
JSON과 동일한 구조지만 Binary 형태로 변경된 구조를 말한다.
그럼 JSON이 있는데 왜 BSON이 등장한 것일까?
몽고DB가 처음 개발될 때에는 JSON을 이용해서 개발을 진행했다고 한다. 그러다가 문제점 몇가지가 나타나기 시작한 것이다.
- JSON은 텍스트 기반으로 구문 분석이 매우 느리다.
- JSON은 공간 효율성과는 거리가 멀다. (데이터베이스 문제)
이 외에도 여러가지 문제가 발생하여 고안해 낸것이 바로 BJSON 인 것이다.
JSON구조의 좋은점은 그대로 가져가면서 기계가 빠르게 읽을 수 있는 binary 형태로 변경하여 저장을 한 것이다.
동일한 형태로 사람에게 보여질 때에는 JSON의 형태로 보여주고, 저장할 때나 네트워크로 전송할 때에는 BSON 형태로 만들어서 저장 또는 전송한다.
{"hello": "world"}
→ \x16\x00\x00\x00 // total document size
\x02 // 0x02 = type String
hello\x00 // field name
\x06\x00\x00\x00world\x00 // field value
\x00 // 0x00 = type EOO ('end of object')
또한 JSON에서는 표현할 수 있는 방법이 문자열, boolean, 숫자, 배열 뿐이다.
그에 반해 BSON에서는 조금 더 디테일하게 표현할 수 있다. 예를들어서 숫자의 경우도 Integer, Float, Long, Decimal과 같이 분류가 되며 날짜의 형태도 저장이 가능하다.
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.