테마
NoSQL과 선택 기준
NoSQL(Not only SQL, 비관계형 데이터베이스)은 테이블, 여러 테이블을 키로 이어 읽는 조인(join), 미리 정한 칼럼 구조인 고정 스키마(schema)를 쓰는 관계형 모델 대신, 특정한 읽기·쓰기 방식과 여러 서버로의 확장에 맞춘 저장소들을 묶어 부르는 이름이다. 하나의 제품이 아니라 서로 전혀 다른 네 부류가 있다. 이 문서는 NoSQL이 나온 이유, 네 부류의 차이, "스키마가 없다"는 말의 실제 뜻을 본다. 분산 저장소의 한계를 말하는 CAP 정리(CAP theorem)와 관계형 DB와 고르는 기준은 2편에서 본다.
왜 나왔나
서버 한 대의 CPU·메모리·디스크를 키우는 것을 수직 확장(scale-up), 서버 수를 늘리는 것을 수평 확장(scale-out)이라 한다. 수직 확장은 언젠가 한계에 닿고 값도 급히 비싸진다. RDBMS(Relational Database Management System, 관계형 데이터베이스 관리 시스템)는 여러 테이블을 조인하고 트랜잭션(transaction)으로 여러 행을 한꺼번에 바꾸는 것이 강점인데, 이 강점은 데이터가 여러 서버에 흩어지면 구현하기 어려워진다. 조인할 행을 다른 서버에서 네트워크로 가져와야 하고, 트랜잭션도 모든 서버가 함께 커밋(commit)하거나 함께 취소하도록 서로 맞춰야 하기 때문이다.
그래서 NoSQL 저장소 대부분은 조인과 여러 행에 걸친 트랜잭션을 줄이거나 포기하는 대신, 데이터를 키 기준으로 여러 서버에 나눠 담는 샤딩(sharding)과 여러 서버에 사본을 두는 복제(replication)를 기본으로 설계한다. 데이터 모델을 단순하게 만들어 서버를 늘리는 것만으로 처리량과 용량이 커지게 한 것이다.
네 가지 종류
| 종류 | 데이터 모양 | 잘 맞는 일 | 대표 제품 |
|---|---|---|---|
| 키-값 | 키 하나에 값 하나 | 캐시, 세션, 장바구니 | Redis |
| 문서 | JSON 같은 문서 | 형태가 제각각인 객체 | MongoDB |
| 와이드 칼럼 | 행 키 + 행마다 다른 칼럼 | 쓰기가 많은 대용량 로그·시계열(시각순 측정값) | Cassandra, HBase |
| 그래프 | 노드와 간선 | 여러 단계 관계 탐색 | Neo4j |
- 키-값 저장소(key-value store)는 키로 값을 넣고 꺼내는 것이 전부다. DB는 값 안을 들여다보지 않으므로 값의 필드로는 찾을 수 없지만, 그만큼 단순하고 빠르다.
- 문서 DB(document database)는 JSON과 비슷한 문서를 저장하고, 문서 안 필드로 찾거나 인덱스를 걸 수 있다. 주문과 주문 상품처럼 늘 함께 읽는 데이터를 한 문서에 넣어 두는 설계가 흔한데, 조인을 없애려고 중복을 감수한다는 점에서 반정규화(denormalization)와 같은 발상이다.
- 와이드 칼럼 저장소(wide-column store)는 행 키로 데이터를 여러 서버에 나누고, 한 행 안에 칼럼을 자유롭게 늘린다. 조인이 없으므로 조회 하나에 필요한 값이 이미 한 테이블에 모여 있어야 한다. 그래서 "어떤 조회를 할지"를 먼저 정하고 그 조회에 맞춰 테이블을 설계한다.
- 그래프 DB(graph database)는 사람·상품 같은 노드(node)와 그 사이 관계인 간선(edge)을 저장한다. "친구의 친구가 산 상품" 같은 질의는 관계형 DB라면 단계마다 조인을 한 번씩 더 해야 한다. 그래프 DB는 노드마다 연결된 간선을 직접 들고 있어 간선을 따라가기만 하면 되므로, 단계가 늘어도 비용이 덜 커진다.
스키마리스의 실제 뜻
NoSQL을 스키마리스(schemaless)라고 부르지만, 데이터에 구조가 없다는 뜻은 아니다. 구조를 DB가 쓸 때 검사하지 않을 뿐이고, 그 구조는 데이터를 읽는 애플리케이션 코드가 가진다. 관계형 DB처럼 쓸 때 스키마를 강제하는 방식을 schema-on-write(쓰기 시 스키마), 읽는 쪽이 구조를 해석하는 방식을 schema-on-read(읽기 시 스키마)라 한다.
그래서 필드를 추가할 때 테이블 변경 없이 바로 새 형태의 문서를 넣을 수 있다. 대신 필드 이름을 바꾸면 옛 이름의 문서와 새 이름의 문서가 함께 남으므로, 읽는 코드가 두 형태를 모두 처리하거나 옛 문서를 따로 옮겨야 한다. 필수 값·타입 검사도 애플리케이션이 맡는다. 관계형 DB에서도 구조가 제각각인 일부 속성만 JSON 칼럼에 담아 이 유연성을 부분적으로 얻을 수 있다.
분산 저장소가 무엇을 포기하는지(CAP 정리와 최종 일관성(eventual consistency))와 관계형 DB와의 선택 기준은 NoSQL과 선택 기준 2에서 이어 본다.
면접 포인트
- NoSQL = Not only SQL. 키-값·문서·와이드 칼럼·그래프 네 부류. 공통점은 수평 확장을 위해 조인·다중 행 트랜잭션을 줄인 것.
- 문서 DB의 내장 문서 설계는 조인을 없애려고 중복을 감수하는 반정규화와 같은 발상.
- 스키마리스 = 스키마가 없는 게 아니라 읽는 코드가 스키마를 가진다(schema-on-read). 필드 이름 변경·검증 부담이 애플리케이션으로 온다.
