컴퓨터 구조 운영체제 네트워크 자료구조 알고리즘 데이터베이스 내 학습
db · 10

NoSQL

DBNoSQLMongoDB

RDBMS는 고정된 스키마와 JOIN에 강하지만, 데이터 형태가 자주 바뀌거나 여러 서버로 수평 확장해야 하는 상황에는 맞지 않을 수 있습니다. NoSQL은 이런 상황을 위해 나온, 서로 다른 데이터 모델을 가진 여러 DB 종류를 묶어 부르는 이름입니다.

핵심 개념

RDBMS vs NoSQL

RDBMS는 고정 스키마와 JOIN 중심, NoSQL은 유연한 스키마와 수평 확장 중심으로 설계 철학이 다릅니다.

핵심 개념

Key-Value

키 하나로 값 하나를 저장/조회하는 가장 단순한 모델입니다(예: Redis). 빠르지만 관계 표현이 약합니다.

핵심 개념

Document

JSON과 비슷한 문서 단위로 저장합니다(예: MongoDB). 관련 데이터를 한 문서에 중첩해 한 번에 가져올 수 있습니다.

핵심 개념

Graph

데이터를 노드와 관계(엣지)로 표현합니다(예: Neo4j). 관계를 여러 단계 타고 들어가는 탐색에 특화되어 있습니다.

핵심 개념

CAP 정리

분산 시스템은 네트워크 분단(Partition tolerance)이 필수 전제이고, 분단이 실제로 발생하면 일관성(C)과 가용성(A) 중 하나를 택해야 합니다.

핵심 개념

언제 NoSQL을 쓰는가

스키마가 자주 바뀌거나, 수평 확장이 중요하거나, 조회 패턴이 관계보다 단순한 경우에 유리합니다.

"대체"가 아니라 "용도가 다름" — NoSQL이 RDBMS보다 무조건 낫거나 못한 게 아니라, 데이터 형태와 조회 패턴에 따라 더 잘 맞는 도구가 다를 뿐입니다.
Document DB도 결국 관계는 생깁니다 — 처음엔 문서 하나로 충분했던 데이터도 서비스가 커지면 다른 문서를 참조해야 하는 경우가 생기고, 그때부터는 RDBMS의 JOIN 없이 이를 흉내 내야 합니다.
CAP 정리의 실제 의미 — 네트워크 파티션이 실제로 발생했을 때(노드 간 통신 장애), 요청을 거부해서 일관성을 지킬지, 오래된 데이터라도 응답해서 가용성을 지킬지의 선택입니다.
이 시각화에서 확인할 것 — "Key-Value" / "Document" / "Graph" 탭에서 같은 사용자·주문 데이터가 각 모델에서 어떻게 다른 모양으로 표현되는지 STEP으로 비교하세요.

NoSQL이 나온 배경

2000년대 중반 웹 서비스가 커지면서 트래픽과 데이터를 여러 서버로 나눠 처리해야 하는 일이 늘었습니다. 구글의 Bigtable(2006) 논문과 아마존의 Dynamo(2007) 논문이 관계형 모델을 따르지 않는 분산 저장소의 설계를 공개했고, 이 논문들의 영향을 받은 Cassandra(Dynamo의 분산 방식과 Bigtable의 데이터 모델), HBase(Bigtable 모델) 같은 오픈소스가 나왔고 같은 시기에 MongoDB 같은 문서 DB도 등장했습니다. 'NoSQL'이라는 이름은 2009년 6월 샌프란시스코에서 열린 오픈소스 분산 비관계형 DB 모임의 이름에서 퍼졌고, 이후 'Not Only SQL'로 풀이하는 경우가 많습니다.

모델과 일관성 용어 더 보기

개념

와이드 컬럼 (Wide-column)

키를 기준으로 데이터를 여러 노드에 나눠 저장합니다. Bigtable과 HBase는 행 키와 컬럼 패밀리로, Cassandra는 테이블과 파티션 키로 구성합니다.

개념

최종 일관성 (Eventual Consistency)

쓰기가 모든 복제본에 퍼지기 전에는 복제본마다 값이 다를 수 있지만, 새로운 쓰기가 없으면 결국 모두 같은 값으로 수렴한다는 보장입니다.

개념

BASE

Basically Available, Soft state, Eventually consistent의 줄임말로, 트랜잭션의 ACID와 대비해 가용성과 확장성을 우선하는 설계 태도를 가리킵니다.

자주 하는 오해

NoSQL은 SQL을 쓰지 않는다 — Cassandra는 CQL이라는 SQL과 비슷한 질의 언어를 씁니다. 'Not Only SQL'이라는 풀이도 SQL을 아예 버린다는 뜻이 아니라는 의미로 쓰입니다.
NoSQL은 트랜잭션이 없다 — 제품마다 다릅니다. MongoDB는 4.0부터 레플리카 셋에서, 4.2부터 샤드 클러스터에서 여러 문서에 걸친 ACID 트랜잭션을 지원합니다. 다만 문서 하나에 대한 연산이 기본적으로 원자적이라서, 관련 데이터를 한 문서에 담아 트랜잭션 없이 해결하는 설계가 많은 경우 적합하다고 안내합니다.
NoSQL은 항상 RDBMS보다 빠르고 확장성이 좋다 — 대체로 조회 패턴에 맞게 데이터를 설계했을 때 그렇습니다. 키로 한 번에 읽는 조회에는 빠르지만, 임의 조건 검색이나 집계, 여러 데이터를 잇는 조회가 많으면 오히려 불리합니다.
JSON을 저장하려면 NoSQL을 써야 한다 — PostgreSQL은 jsonb 타입과 인덱스로 JSON 문서를 저장하고 검색할 수 있습니다. 관계형 DB 안에서 일부 데이터만 문서처럼 다루는 선택도 가능합니다.
CAP 때문에 평소에도 일관성을 포기한다 — CAP는 네트워크 분단이 났을 때의 선택입니다. 분단이 없는 평소에도 응답 지연과 일관성 사이의 절충이 있다는 점은 Daniel Abadi가 PACELC로 정리했습니다.

면접에서 이렇게 물어요

면접 질문

RDBMS와 NoSQL 중 무엇을 고르나요?

정답이 정해져 있지 않고 조회 패턴으로 고릅니다. 데이터 사이의 관계가 복잡하고 트랜잭션과 임의 조건 질의가 중요하면 RDBMS, 키 기반 조회와 대량 쓰기, 스키마 변화, 수평 확장이 중요하면 NoSQL이 맞습니다. 두 가지를 함께 쓰는 구성도 있습니다.

면접 질문

Document DB에서 임베딩과 참조는 어떻게 고르나요?

함께 읽는 데이터는 한 문서에 임베딩해 한 번에 읽습니다. 자주 바뀌거나 여러 곳에서 공유하거나 계속 커지는 데이터는 참조로 분리합니다. MongoDB는 문서 하나의 크기에 16MiB 상한이 있어서 계속 커지는 배열을 임베딩하면 한계에 부딪힙니다.

면접 질문

최종 일관성은 언제 받아들일 수 있나요?

잠깐 오래된 값을 읽어도 문제가 없는 경우입니다. 좋아요 수, 조회 수, 피드 같은 데이터가 그렇고, 계좌 잔액처럼 읽은 값이 항상 최신이어야 하는 데이터에는 맞지 않습니다.

면접 질문

NoSQL에서 샤딩이 상대적으로 쉬운 이유는 무엇인가요?

키 단위로 접근하는 설계가 많아서 키를 기준으로 데이터를 나눠도 JOIN이 필요 없습니다. 관계형은 샤드를 넘나드는 JOIN과 트랜잭션의 비용이 커집니다.

실제 시스템에서는

Redis — 메모리에 데이터를 두는 키-값 저장소로, 값에 문자열뿐 아니라 해시, 리스트, 집합, 정렬 집합 같은 자료구조를 쓸 수 있습니다. 캐시나 순위표(리더보드)가 대표적인 용도입니다.
Cassandra — 마스터 없이 모든 노드가 동등한 구조이고 파티션 키로 데이터를 노드에 분산합니다. 읽기와 쓰기마다 ONE, QUORUM, ALL 같은 일관성 수준을 고를 수 있습니다.
Dynamo 논문 — 일관된 해싱(consistent hashing)으로 데이터를 나누고 최종 일관성을 택한 설계를 설명하며, 장바구니 서비스를 사례로 듭니다.

함께 보면 좋은 토픽

샤딩 — 데이터를 여러 서버로 나누는 기준과 그 비용을 봅니다.
복제 — 복제본 사이에서 일관성과 가용성이 어떻게 갈리는지 봅니다.
트랜잭션 — ACID가 무엇을 보장하는지 NoSQL의 선택과 비교해 봅니다.
RDBMS 기초 — NoSQL과 대비되는 관계형 모델의 기본을 봅니다.

참고 자료

Key-Value — 저장/조회는 항상 "키 하나 → 값 하나"

-- 사용자 정보와 주문 내역을 서로 다른 키로 따로 저장
SET user:1001 '{"name":"Alice","grade":"VIP"}'
SET orders:1001 '["Order#1","Order#2"]'

-- 조회도 키 하나씩: 두 값을 합치는 건 애플리케이션 몫
GET user:1001
GET orders:1001

Key-Value 저장소는 인덱스나 JOIN 개념이 없습니다. 대신 O(1)에 가까운 조회 속도를 얻는 대신, "사용자와 주문을 함께 보여줘" 같은 요청은 두 번 조회해서 애플리케이션이 직접 합쳐야 합니다.

Document — 관련 데이터를 문서 하나에 중첩

// 사용자와 주문을 한 문서 안에 함께 저장
{
  "_id": "user:1001",
  "name": "Alice",
  "orders": [
    { "id": "Order#1", "amount": 32000 },
    { "id": "Order#2", "shipTo": { "city": "Seoul" } }
  ]
}

// 문서 하나만 조회하면 사용자+주문을 한 번에 얻음
db.users.findOne({ _id: "user:1001" })

Key-Value와 달리 관련 데이터를 미리 한 문서에 묶어두면, Key-Value에서 두 번 조회하던 걸 한 번으로 줄일 수 있습니다. 대신 문서 크기가 커지거나 같은 정보가 여러 문서에 중복 저장될 수 있다는 트레이드오프가 있습니다.

Graph — 관계 자체를 질의하기

// 노드 생성
CREATE (a:User {name: 'Alice'})
CREATE (o:Order {id: 'Order#1'})
CREATE (a)-[:ORDERED]->(o)

// "Alice가 주문한 것들"을 관계를 따라가며 조회
MATCH (a:User {name: 'Alice'})-[:ORDERED]->(o:Order)
RETURN o

RDBMS라면 users 테이블과 orders 테이블을 JOIN해야 할 조회가, Graph DB에서는 이미 존재하는 관계(엣지)를 따라가는 탐색이 됩니다. 관계 단계가 여러 겹(친구의 친구의 친구)일수록 이 차이는 더 커집니다.

Q1

Key-Value 모델의 가장 큰 특징은?

가장 단순한 저장 모델입니다.
Key-Value는 키 하나로 값 하나를 저장/조회하는 가장 단순한 모델입니다. 빠르지만 여러 키에 걸친 관계 표현은 애플리케이션이 직접 처리해야 합니다.

Q2

Document 모델이 Key-Value보다 유리한 점은?

사용자 정보와 주문 내역을 한 문서에 같이 넣으면?
Document 모델은 관련 데이터를 하나의 문서(JSON 등)에 중첩해서 저장할 수 있어, Key-Value처럼 여러 키를 따로 조회할 필요 없이 문서 하나로 관련 정보를 한 번에 가져올 수 있습니다.

Q3

Graph DB가 관계 탐색에 강한 이유는?

RDBMS라면 JOIN으로 계산해야 할 것을, Graph는 미리 저장해둔 관계를 따라갑니다.
Graph DB는 노드(정점)와 관계(엣지)로 데이터를 표현해, "친구의 친구" 같은 다단계 관계 탐색을 JOIN 없이 관계를 따라가는 방식으로 빠르게 처리할 수 있습니다.