ㅁㄴㅇㄻㄴㅇㄹ

[DB] MongoDB 자료구조 본문

DB

[DB] MongoDB 자료구조

hanbin8269 2022. 6. 1. 00:50

MongoDB는 도큐먼트 지향적인 데이터베이스다.

내부적으로 MongoDB는 Binary JSON의 형태로 도큐먼트를 저장한다.

 

MYSQL은 데이터를 테이블에 행으로서 저장하는 반면

MongoDB가 도큐먼트의 모음과 같이 데이터를 컬렉션에 도큐먼트로 저장한다.

 

MYSQL와 같은 RDBMS는 한 객체의 데이터를 여러개의 테이블로 나누어 표현하는 정규화를 거치는데, 정규화를 너무 많이 한다면 그에 따른 비용이 들어가게 된다.

이는 곧 데이터를 모으는 작업을 해야 한다는 것이다.

예를 들어서 블로그 글 하나를 보여주기 위해서 post와 comment 테이블에 대한 조인 연산이 필요해 진다.

하지만 도큐먼트 지향적인 데이터 모델(MongoDB)에서는 객체를 자연스럽게 모아놓은 형태로 표현함으로 객체를 전체적으로 작업할 수 있다는 점이 있다.

위에서 post 와 comment 등의 블로그 글 하나를 표현하는 모든 데이터 들이 하나의 데이터베이스 객체에 들어갈 수 있다.

스키마가 없는 모델

도큐먼트에는 미리 정해진 스키마가 없다. RDBMS에서는 데이터 열을 테이블에 저장하지만, 각 테이블은 각각의 컬럼에 대해 허용되는 데이터 타입을 명시한다.

이렇게 스키마가 없다는 것은 아래와 같은 장점이 있다.

첫번째로 데이터베이스가 아닌 애플리케이션이 데이터구조를 정한다는 것이다. 이것은 데이터의 구조가 빈번히 변경되는 개발 초기단계에서 개발 속도를 단축시켜 준다.

두번째로 가변적인 속성을 갖는 데이터를 표현할 수 있다는 것이다. 예를 들어 상품 판매 사이트를 만든다고 했을때, 하나의 상품이 어떤 속성을 갖게 될 지 미리 알 수 없으므로 애플리케이션에서는 이러한 가변적인 속성을 처리할 수 있어야 한다.

이런점에서 MongoDB는 새로운 속성은 도큐먼트에 동적으로 처리할 수 있기 때문에 추후에 필요한 데이터필드가 무엇일지 고민할 필요가 없다.

고정된 스키마를 갖는 데이터베이스에서는 EAV(Entity-Attribute-Value) 패턴을 이용한다.

Entity-Attribute-Value model?

데이터베이스 설계 시 오브젝트의 자유도를 최대한 보장해야 하는 경우 고려 가능한 모델

잠재적인 어트리뷰트는 많지만 실제 사용되는 어트리뷰트 수는 적을 떄 사용되는 데이터 모델이다.

  • Entity는 테이블에서의 엔터티 객체를 나타낸다.
  • Attribute는 객체의 어트리뷰트(Field)이다.
  • Value는 객체의 어트리뷰트의 값이다.

애드혹 쿼리

**애드혹 쿼리(ad hoc query)**란 아래 예제처럼 미리 정의된 쿼리가아닌 아래와 같이 파라미터가 늘 변하게되는 변수로 작용하는 되는 쿼리이다. (**user_id**가 매번 변함)

query = "SELECT * FROM users WHERE id=" + user_id

RDBMS만 사용해 봤다면 애드혹 쿼리를 당연한 것으로 생각하기 쉽지만, 사실 모든 데이터베이스가 이런 동적 질의를 지원하는 것은 아니다.

다른 많은 시스템에서 간단하고 확장성 높은 모델을 위해 풍부한 쿼리 기능을 포기하는 경우가 많은데,

MongoDB의 설계 목표 중 하나는 관계형 데이터베이스상에서 매우 필수적은 쿼리 성능을 유지하는 것이다.

MongoDB에서 쿼리 언어는 아래와 같이 작동한다.

db.posts.find({'tags': 'politics', 'vote_count': {'$gt': 10}})

SQL 쿼리는 엄격하게 정규화 된 모델에 의존하는 반면, MongoDB의 쿼리는 태그가 각 도큐먼트에 포함되어 있다고 가정한다.

여러개의 속성 (tags 검색, vote_count 검색)을 조합하여 질의할 수 있는 능력을 보여주는데, 이것이 애드혹 쿼리의 본질적인 강점이다.

인덱스

MongoDB에서 인덱스는 B-Tree(B-Tree?) 로 구현되어 있다.

관계 데이터베이스에서 기본적으로 제공하는 기능인 인덱스는 범위를 스캔하거나 정렬을 하는 것과 같이 간단한 쿼리에 대해 최적화 되어 있다.

하지만 WiredTiger는 LSM tree(Log-Structed Merge-trees)를 지원한다고 한다.

B-Tree?

이진 트리가 자식 노드가 최대 2개인 노드를 말하는 것이라면 B-Tree는 자식 노드의 개수가 2개 이상인 트리를 말한다.

또한 노드내의 데이터가 1개 이상일 수가 있다. 만약 노드 내 최대 데이터 수가 2개라면 2차 B-Tree, 3개라면 3차 B-Tree라고 말한다.

그리고, 노드의 데이터 수가 N개라면 자식 노드의 개수는 N+1개 이다.

또한, 6보다 작은 값은 왼쪽 서브트리, 6과 17 사이의 값은 중간 서브트리, 17보다 큰 값은 오른쪽 서브트리에 들어가는 구조를 볼 수 있다.

탐색법은 작은 값은 왼쪽, 큰값은 오른쪽에 있기 때문에 root 노드부터 시작해 하향식으로 탐색해 나간다.

내부적으로 MongoDB는 Binary JSON의 형태로 도큐먼트를 저장한다.

BSON(Binary JSON)은 무엇인가?

MYSQL은 데이터를 테이블에 행으로서 저장하는 반면

MongoDB가 도큐먼트의 모음과 같이 데이터를 컬렉션에 도큐먼트로 저장한다.

MYSQL와 같은 RDBMS는 한 객체의 데이터를 여러개의 테이블로 나누어 표현하는 정규화를 거치는데, 정규화를 너무 많이 한다면 그에 따른 비용이 들어가게 된다.

이는 곧 데이터를 모으는 작업을 해야 한다는 것이다.

예를 들어서 블로그 글 하나를 보여주기 위해서 post와 comment 테이블에 대한 조인 연산이 필요해 진다.

하지만 도큐먼트 지향적인 데이터 모델(MongoDB)에서는 객체를 자연스럽게 모아놓은 형태로 표현함으로 객체를 전체적으로 작업할 수 있다는 점이 있다.

위에서 post 와 comment 등의 블로그 글 하나를 표현하는 모든 데이터 들이 하나의 데이터베이스 객체에 들어갈 수 있다.

스키마가 없는 모델

도큐먼트에는 미리 정해진 스키마가 없다. RDBMS에서는 데이터 열을 테이블에 저장하지만, 각 테이블은 각각의 컬럼에 대해 허용되는 데이터 타입을 명시한다.

이렇게 스키마가 없다는 것은 아래와 같은 장점이 있다.

첫번째로 데이터베이스가 아닌 애플리케이션이 데이터구조를 정한다는 것이다. 이것은 데이터의 구조가 빈번히 변경되는 개발 초기단계에서 개발 속도를 단축시켜 준다.

두번째로 가변적인 속성을 갖는 데이터를 표현할 수 있다는 것이다. 예를 들어 상품 판매 사이트를 만든다고 했을때, 하나의 상품이 어떤 속성을 갖게 될 지 미리 알 수 없으므로 애플리케이션에서는 이러한 가변적인 속성을 처리할 수 있어야 한다.

이런점에서 MongoDB는 새로운 속성은 도큐먼트에 동적으로 처리할 수 있기 때문에 추후에 필요한 데이터필드가 무엇일지 고민할 필요가 없다.

고정된 스키마를 갖는 데이터베이스에서는 EAV(Entity-Attribute-Value) 패턴을 이용한다.

Entity-Attribute-Value model?

데이터베이스 설계 시 오브젝트의 자유도를 최대한 보장해야 하는 경우 고려 가능한 모델

잠재적인 어트리뷰트는 많지만 실제 사용되는 어트리뷰트 수는 적을 떄 사용되는 데이터 모델이다.

  • Entity는 테이블에서의 엔터티 객체를 나타낸다.
  • Attribute는 객체의 어트리뷰트(Field)이다.
  • Value는 객체의 어트리뷰트의 값이다.

애드혹 쿼리

**애드혹 쿼리(ad hoc query)**란 아래 예제처럼 미리 정의된 쿼리가아닌 아래와 같이 파라미터가 늘 변하게되는 변수로 작용하는 되는 쿼리이다. (**user_id**가 매번 변함)

query = "SELECT * FROM users WHERE id=" + user_id

RDBMS만 사용해 봤다면 애드혹 쿼리를 당연한 것으로 생각하기 쉽지만, 사실 모든 데이터베이스가 이런 동적 질의를 지원하는 것은 아니다.

다른 많은 시스템에서 간단하고 확장성 높은 모델을 위해 풍부한 쿼리 기능을 포기하는 경우가 많은데,

MongoDB의 설계 목표 중 하나는 관계형 데이터베이스상에서 매우 필수적은 쿼리 성능을 유지하는 것이다.

MongoDB에서 쿼리 언어는 아래와 같이 작동한다.

db.posts.find({'tags': 'politics', 'vote_count': {'$gt': 10}})

SQL 쿼리는 엄격하게 정규화 된 모델에 의존하는 반면, MongoDB의 쿼리는 태그가 각 도큐먼트에 포함되어 있다고 가정한다.

여러개의 속성 (tags 검색, vote_count 검색)을 조합하여 질의할 수 있는 능력을 보여주는데, 이것이 애드혹 쿼리의 본질적인 강점이다.

인덱스

MongoDB에서 인덱스는 B-Tree(B-Tree?) 로 구현되어 있다.

관계 데이터베이스에서 기본적으로 제공하는 기능인 인덱스는 범위를 스캔하거나 정렬을 하는 것과 같이 간단한 쿼리에 대해 최적화 되어 있다.

 

하지만 WiredTiger는 LSM tree(Log-Structed Merge-trees)를 지원한다고 한다.

B-Tree?

이진 트리가 자식 노드가 최대 2개인 노드를 말하는 것이라면 B-Tree는 자식 노드의 개수가 2개 이상인 트리를 말한다.

또한 노드내의 데이터가 1개 이상일 수가 있다. 만약 노드 내 최대 데이터 수가 2개라면 2차 B-Tree, 3개라면 3차 B-Tree라고 말한다.

그리고, 노드의 데이터 수가 N개라면 자식 노드의 개수는 N+1개 이다.

또한, 6보다 작은 값은 왼쪽 서브트리, 6과 17 사이의 값은 중간 서브트리, 17보다 큰 값은 오른쪽 서브트리에 들어가는 구조를 볼 수 있다.

탐색법은 작은 값은 왼쪽, 큰값은 오른쪽에 있기 때문에 root 노드부터 시작해 하향식으로 탐색해 나간다.

'DB' 카테고리의 다른 글

[DB] MongoDB 장점  (0) 2022.06.01
[DB] Lock 이해하기  (0) 2022.05.20
[DB] 상황에 맞는 인덱스 사용법  (0) 2022.05.20