<데이터베이스> 관계형 vs. NoSQL 언제 무엇을 써야할까?

|
매번 아랑고DB에 관한 글만 다루다가, 오늘은 회사에서 간단하게 RDB vs. NoSQL에 대해 세미나를 진행한 내용이 있어 공유하려고 한다. 데이터베이스에 대해 공부하게 되면 정말 많이 찾아보게 되는 글인데, 사실 이론적인 부분보다는 내가 직접 쓰면서 느낀 경험적 측면에서 써보려고 한다.
여기서 읽는 내용들은 "참고"만 하자. 이론적으로 정교하게 서술한 글이 아니기 때문에 아 이런 성질이 있나 보구나 하고 가벼운 마음으로 읽기를 강력 추천함

1. RDB (Relational Database)

관계형 데이터베이스로 풀이되는 RDB는 말 그대로 관계형 모델을 기반으로 하는 데이터베이스이다. 이를 유지하고 관리하기 위한 시스템을 RDBMS (- Management System) 이라고 부른다.

그리고 이러한 RDBMS는 주로 SQL(Structured Query Lang)을 이용해 데이터를 조회하고, 관리하게 된다. 이 글에 DML, DDL, DCL 등에 대한 설명이 간결하게 잘 되어있는 것 같다.

관계형 데이터베이스의 특징은 아래와 같다.

  1. 2차원 데이터로 표현된다 (행/열)
  2. 상호관련성을 가진 테이블의 집합으로 구성된다
  3. 테이블 사이의 관계를 외래키로 나타낸다
  4. 스키마 변경이 어렵다
  5. Vertical Scalable 하지만, Horizontal scale은 어렵다
  6. 메인테넌스 코스트 / 사용 요금이 비싸다
  7. SQL을 사용해 데이터를 질의한다
  8. ACID 성질을 갖는다

여기서 몇가지만 자세히 다루고 넘어가자.

4 스키마 변경이 어렵다

RDB는 매우 정교한 초기 설계로 만들어진다. 테이블 사이에 서로 의존성이 있고, 쳇바퀴처럼 맞물려 돌기 때문에 데이터 타입을 바꾼다든지 새로운 열을 추가한다든지 하는 작업은 실제 프로덕션 환경에서 사실상 불가능하다.

보통 기존 테이블을 복제해서 거기에 수정을 가한 뒤, 기존 테이블과 교체하는 방식을 택한다.

5 스케일링

일반적으로 Vertical Scaling은 하드웨어 스펙의 확장을 의미하고, Horizontal Scaling은 양적 확장을 의미한다.

RDB가 수직 확장이 더 용이하고 수평 확장이 어려운 이유는, 데이터가 여러 테이블에 의존해있기 때문이다.

데이터가 서버에 분산될 경우 이를 중간에서 잘 중재해주는 역할이 중요해지는데, 그럴 바에는 그냥 좋은 서버를 하나 사서 분산 처리에 대한 신경을 쓰지 않아도 되기 때문이다.

8 ACID

ACID(원자성 Atomicity, 일관성 Consistency, 고립성 Isolation, 지속성 Durability)는 데이터베이스 트랜잭션의 성질을 나타낸다.

자세한 내용은 여기 읽어보자. 나중에 기회되면 공부해서 제대로 다루겠음

2. NoSQL Database

이러한 RDB에 대응되는 녀석이 NoSQL 데이터베이스다. Non-SQL 이라고도 하고, Not only SQL 의 약자라고도 한다.

아무튼 이들은 관계형이 아닌 데이터 모델을 총칭하고, 도큐먼트 모델 / 키-값 모델 / 그래프 모델 / 와이드 컬럼 모델 등 다양한 데이터 모델이 있다.

NoSQL 데이터베이스의 특징은 아래와 같다.

  1. 다양한 방식으로 데이터를 표현한다
  2. 테이블(혹은 컬렉션 혹은 또 다른 명칭) 사이에 딱히 명시된 제약이나 규칙이 없다
  3. 스키마가 고정적이지 않고, 매우 유연하다
  4. Horizontal Scale이 쉽다
  5. 코스트 저렴 / 오픈소스도 많다
  6. 연산이 빠르고 빅데이터 & 실시간 연산에 적합하다

1 다양한 방식으로 데이터를 표현한다

NoSQL 방식의 데이터 모델의 예시를 살펴보면, 아래 그림과 같이 표현할 수 있다. 출처 요기

NoSQL Data Models

  • 도큐먼트 모델은 레코드 하나를 오브젝트(도큐먼트) 형식으로 표현한다. 자유로운 스키마 구조를 가지며 구조가 확정되지 않은 데이터를 밀어넣고, 자유롭게 작업하기 좋다. 몽고DB나 아랑고DB가 대표적인 예시이다.
  • 그래프 모델은 데이터를 버텍스와 엣지로 그래프에 표현하는 방식이다. 데이터 사이의 유기적인 관계를 표현하기에 적합하다. 대표적인 예로 Neo4j와 ArangoDB, Gremlin 등이 있다. 아랑고DB에 대해서는 현재 블로그에서 다루고 있으니 궁금하면 여기
  • 키/값 모델은 하나의 키에 값을 맵핑하는 해시 구조의 데이터 모델이다. 빠르게 데이터에 접근할 수 있는 장점이 있다. 대표적인 예로 redis가 있음
  • 와이드 컬럼 모델은 테이블 형태를 취하지만 행마다 갖는 컬럼의 형태가 고정되어 있지 않은 데이터 모델이다. 언뜻 와닿지 않는 내용인데, 이 글을 참고하길 바란다.

3. RDB vs. NoSQL

그럼 이제 둘을 비교해보자.

  • RDB는 관계형으로 데이터를 저장하지만, NoSQL은 그렇지 않다.
  • RDB는 스키마가 정적이지만, NoSQL은 유연한 스키마 구조를 갖는다.
  • RDB는 수직 확장이 용이하고, NoSQL은 수평 확장이 용이하다. (즉, RDB는 서버 용량을 늘리는 게 쉽고, NoSQL은 서버를 여러 대 늘리는 게 쉽다)
  • 위와 관련해서, RDB는 확장 시 다운타임이 있을 수 있지만, NoSQL은 거의 없다.
  • RDB는 복잡한 쿼리와 Join 연산이 가능하다. NoSQL은 구조화된 쿼리 언어가 없는 경우도 많고, 일반적으로 Join이 없다.
  • RDB는 OLTP에 적합하고, NoSQL은 OLAP에 적합하다. (즉, RDB는 트랜잭션 처리에 용이하고, NoSQL은 분석 처리에 용이하다)

4. 언제 어떤 데이터베이스를 사용할까?

3번과 비슷한 이야기지만, 실제 내가 사용하고 있는 환경에 빗대어 내 경험을 토대로 이야기해보겠다.

RDB - MySQL

RDB 중 하나인 MySQL은 보통 관계형으로 잘 정리될 수 있는 고객 데이터나 비즈니스 데이터, 결제 데이터 등을 다룰 때 사용한다.

  • 테이블마다 연관되는 키가 잘 드러나기 때문에 관계형으로 표현하는게 매우 효율적이다 (JOIN 연산!)
  • 트랜잭션을 통해 OLTP의 역할을 해야할 때
  • 트랜잭션의 ACID가 보장되어야 할 때 (Dirty read..)

NoSQL - MongoDB

몽고DB는 아주 유용한 녀석이다. 도큐먼트 모델이기 때문에 넣는 데이터의 스키마에 구애받을 필요가 없다.

  • 중간 분석 데이터를 편하게 밀어넣어 두고, 꺼내쓰기가 편리함
  • 단, SQL에서는 간단한 쿼리문이 몽고DB의 언어로 바뀌면 수행하기가 어렵기 때문에 애초에 데이터를 잘 가공해서 넣어둠
  • 최종적으로 사용할 데이터를 넣어두는 용도로도 많이 씀
  • 한마디로 막쓰기 정말 좋음, 심지어 안정적이다

NoSQL - redis

redis는 인메모리 키-값 모델이다. 말그대로 인-메모리이기 때문에 데이터 접근 & 대기시간이 매우 매우 짧다. 따라서 주로 데이터 캐시, 메시지 브로커 & 대기열로 쓰임

  • 동시에 대량의 트래픽을 처리하는 웹서비스에서 데이터를 캐시하는 중간 DB 역할로 많이 씀 (1만명이 MySQL 칠 트래픽을 redis가 값을 가져와서 막아준다고 생각하면 됨)
  • celery, airflow 등의 분산 처리 프레임워크에서 메시지 브로커로 많이 쓴다. (‘분산’ 처리이기 때문에 워커나 태스크 사이의 데이터를 주고받을 때 중개자가 필요함. 그 역할을 수행한다)

NoSQL - ArangoDB

아랑고DB는 멀티 모델 데이터베이스이다. 즉, 도큐먼트 모델도 지원하지만 그래프 모델도 지원한다.

  • 그래프 모델은 데이터 분석의 깊이가 깊어질수록 그 진가를 발휘한다고 생각한다.
  • ‘내 친구의 친구가 좋아하는 영화의 감독이 만든 다른 영화들의 주연들의 목록’을 기존 데이터베이스로 뽑는다고 생각해보자. 아찔하다.
  • 그래프DB는 간단한 횡단(traversal) 쿼리로 이를 구현할 수 있다.
  • 물론, 초기 그래프 구조 설계가 효율에 많은 영향을 미치며, 쿼리 튜닝도 중요함

5. 마치며

이렇게 간단하게 RDB와 NoSQL 데이터베이스를 비교하는 시간을 가졌다. 각각을 심층적으로 모두 다루긴 어렵겠지만, 각 DB를 사용하며 겪었던 여러 이슈들이나 알면 좋은 개념들은 지속적으로 업데이트 할 생각이다!