NoSQL
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이 나온 배경
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와 대비해 가용성과 확장성을 우선하는 설계 태도를 가리킵니다.
자주 하는 오해
면접에서 이렇게 물어요
면접 질문
RDBMS와 NoSQL 중 무엇을 고르나요?
정답이 정해져 있지 않고 조회 패턴으로 고릅니다. 데이터 사이의 관계가 복잡하고 트랜잭션과 임의 조건 질의가 중요하면 RDBMS, 키 기반 조회와 대량 쓰기, 스키마 변화, 수평 확장이 중요하면 NoSQL이 맞습니다. 두 가지를 함께 쓰는 구성도 있습니다.
면접 질문
Document DB에서 임베딩과 참조는 어떻게 고르나요?
함께 읽는 데이터는 한 문서에 임베딩해 한 번에 읽습니다. 자주 바뀌거나 여러 곳에서 공유하거나 계속 커지는 데이터는 참조로 분리합니다. MongoDB는 문서 하나의 크기에 16MiB 상한이 있어서 계속 커지는 배열을 임베딩하면 한계에 부딪힙니다.
면접 질문
최종 일관성은 언제 받아들일 수 있나요?
잠깐 오래된 값을 읽어도 문제가 없는 경우입니다. 좋아요 수, 조회 수, 피드 같은 데이터가 그렇고, 계좌 잔액처럼 읽은 값이 항상 최신이어야 하는 데이터에는 맞지 않습니다.
면접 질문
NoSQL에서 샤딩이 상대적으로 쉬운 이유는 무엇인가요?
키 단위로 접근하는 설계가 많아서 키를 기준으로 데이터를 나눠도 JOIN이 필요 없습니다. 관계형은 샤드를 넘나드는 JOIN과 트랜잭션의 비용이 커집니다.
실제 시스템에서는
함께 보면 좋은 토픽
참고 자료
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 모델의 가장 큰 특징은?
Q2
Document 모델이 Key-Value보다 유리한 점은?
Q3
Graph DB가 관계 탐색에 강한 이유는?