본문으로 바로가기

19

SQL과 NoSQL

데이터를 어떤 모양으로 보관할지 정하는 일이, 나중에 무엇을 빠르게 할 수 있는지를 결정한다

먼저 보면 좋은 강의: 웹 요청의 해부, 지연 시간과 처리량

단계별로 보기

스페이스바로 재생/정지, 좌우 화살표로 단계 이동, R로 처음으로 돌아갑니다.

대기 중1 / 4 단계 — 관계형 — 꺼낼 때 합친다

사용자가 프로필 화면을 엽니다. 관계형 저장소에서는 이 화면에 필요한 정보가 여러 곳에 나뉘어 있습니다. 인사 정보, 급여 정보, 부서 정보를 각각 꺼내 서버가 합쳐야 합니다. 이 '합치는 일'이 조인이고, 여기에 시간이 듭니다.

이 강의를 마치면

  • 관계형(SQL) 저장소가 데이터를 쪼개어 보관하고 읽을 때 다시 합치는 방식임을 설명한다.
  • 문서형(NoSQL) 저장소가 미리 합쳐 두고 한 번에 꺼내는 방식임을 설명한다.
  • 두 방식의 이득과 대가가 각각 무엇인지 구분한다.
  • 하나의 서비스가 두 저장소를 함께 쓰는 것이 타협이 아니라 정상적인 설계임을 안다.

서류를 어떻게 보관할 것인가

회사에 직원 정보가 있다고 합시다. 이걸 정리하는 방법은 두 가지입니다.

방법 A — 항목별로 나눠서 보관한다. 인사 카드는 인사 서랍에, 급여 내역은 급여 서랍에, 부서 정보는 부서 서랍에 넣습니다. 각 정보는 딱 한 곳에만 있습니다.

방법 B — 사람별로 묶어서 보관한다. "김철수" 폴더 하나에 그 사람의 인사, 급여, 부서 정보를 전부 넣습니다. 한 사람에 대해 알아야 할 게 있으면 그 폴더 하나만 꺼내면 됩니다.

이게 정확히 관계형(SQL)문서형(NoSQL)의 차이입니다.

방법 A가 좋을 때 — 고칠 일이 많다

"영업부" 이름이 "세일즈부"로 바뀌었다고 합시다.

방법 A에서는 부서 서랍의 카드 한 장만 고치면 끝입니다. 직원이 만 명이어도 마찬가지입니다. 부서 이름은 원래 한 곳에만 있었으니까요.

방법 B에서는 영업부 소속 직원 폴더를 전부 찾아서 하나씩 고쳐야 합니다. 하나라도 놓치면 그 사람만 아직 "영업부"입니다. 데이터가 서로 어긋나는 거죠.

방법 B가 좋을 때 — 꺼낼 일이 많다

"김철수의 프로필 화면을 보여줘"라는 요청이 초당 수천 건 들어온다고 합시다.

방법 B는 폴더 하나 꺼내면 끝입니다. 한 번의 조회입니다.

방법 A는 인사 서랍에서 한 장, 급여 서랍에서 한 장, 부서 서랍에서 한 장을 꺼내 책상 위에서 합쳐야 합니다. 이 '합치는 작업'을 조인(join)이라고 부릅니다. 서랍이 많아질수록, 데이터가 많아질수록 이 작업이 비싸집니다.

정리하면

관계형 (SQL)문서형 (NoSQL)
보관 모양항목별로 쪼개 둔다쓸 모양대로 합쳐 둔다
같은 사실이 있는 곳딱 한 군데여러 폴더에 복사됨
고칠 때한 곳만 고치면 됨복사본을 전부 찾아 고쳐야 함
꺼낼 때여러 곳에서 꺼내 합쳐야 함한 번에 꺼냄
잘 맞는 일돈, 주문, 재고처럼 틀리면 안 되는 것프로필, 카탈로그처럼 많이 읽는 것

핵심은 이겁니다. 방법 B의 빠름은 공짜가 아닙니다. 미리 합쳐 두는 대가로 같은 사실이 여러 폴더에 복사됩니다. 그 복사본들을 일치시킬 책임이 저장소에서 여러분의 코드로 옮겨온 것뿐입니다. 비용이 사라진 게 아니라 이사한 겁니다.

"그래서 뭘 써야 하나요"

이 질문 자체가 틀렸습니다. 올바른 질문은 "이 데이터로 무슨 일을 자주 하는가"입니다.

  • 주문과 결제 — 틀리면 돈이 사라집니다. 한 곳에만 두고 정확히 고치는 게 중요합니다. → 관계형
  • 상품 카탈로그 — 하루에 한 번 바뀌고 초당 수천 번 읽힙니다. 빠르게 꺼내는 게 중요합니다. → 문서형

그리고 이 둘은 같은 서비스 안에 공존합니다. 하나의 저장소로 전부 해결하려는 시도가 오히려 예외적인 선택입니다. 큰 서비스가 저장소를 여러 개 쓰는 것은 결정을 못 내려서가 아니라, 일마다 답이 다르기 때문입니다.

이름에 대한 오해 하나. NoSQL은 "SQL을 쓰지 않는다"는 뜻이 아니라 역사적으로 붙은 이름일 뿐입니다. 요즘 문서형 저장소 중에도 SQL과 거의 같은 질의어를 제공하는 게 많습니다. 이름이 아니라 데이터의 모양이 본질입니다.

이 강의가 단순화한 것

교육용 모형은 언제나 무언가를 생략합니다. 무엇을 생략했는지 아는 것도 학습의 일부입니다.

전제한 것

  • 관계형 저장소의 조인 비용을 '질의 시간이 길다'는 하나의 숫자로 뭉뚱그린다. 실제 조인 비용은 테이블 크기, 인덱스, 질의 계획에 따라 수십 배까지 달라진다.
  • 문서형 저장소를 이 강의의 캔버스에서는 '질의가 빠른 데이터베이스 노드'로 표현한다. 실제 문서형 저장소의 내부 구조는 관계형과 근본적으로 다르다.
  • 두 저장소 사이의 데이터 동기화(같은 사실의 복사본을 맞추는 일)는 이 강의에서 시간이 들지 않는 것으로 본다. 실제로는 이 동기화가 가장 어려운 부분이다.
  • SQL/NoSQL의 구분은 실제로는 연속적인 스펙트럼이며, 이 강의의 이분법은 설명을 위한 단순화다.

다루지 않은 것

  • 정규화 단계(1NF~BCNF)의 형식적 정의
  • 키-값, 컬럼 패밀리, 그래프 등 문서형 이외의 NoSQL 갈래
  • 질의 계획기(query planner)와 조인 알고리즘
  • 두 저장소 간 동기화를 위한 CDC(변경 데이터 캡처) 파이프라인

더 읽을거리: Designing Data-Intensive Applications — Chapter 2: Data Models and Query Languages

이제 직접 만들어 보세요

읽어서 아는 것과 만들어서 아는 것은 다릅니다. 컴포넌트를 배치하고 트래픽을 흘려서 실제로 동작하는지 확인해 보세요.

실습 과제 열기

이 강의에 물어보기

하루 5번

이 강의 본문만 근거로 답합니다. 강의에 없는 내용은 지어내지 않습니다.