NoSQL
NoSQL
도구
표 모양을 미리 정해 두지 않고 데이터를 담는 데이터베이스 계열로, 항목이 제각각이거나 양이 크게 늘어나는 데이터에 씁니다.
등장 배경
오랫동안 데이터를 담는 방법은 사실상 하나였습니다. 행과 열이 있는 표를 만들어 놓고 그 칸에 값을 넣는 방식이고, 표에 어떤 칸이 있는지는 데이터를 넣기 전에 미리 정해 둬야 했습니다.
이 전제가 흔들린 건 웹 서비스가 커지면서였습니다. 사용자가 남기는 기록은 기능마다 모양이 달랐고, 새 기능이 붙을 때마다 새 항목이 생겼습니다. 표에 칸을 더하려면 이미 쌓인 수백만 줄을 건드려야 했고, 그동안 서비스가 멈추거나 느려졌습니다. 양도 문제였습니다. 한 대에 다 들어가지 않을 만큼 커지면 여러 대에 나눠 담아야 하는데, 표를 맞춰 읽는 방식은 데이터가 여러 대에 흩어진 순간 부담이 커집니다.
페이지덱에서도 같은 벽에 부딪혔습니다. 태오가 활동 기록을 남기려고 표를 하나 만들었는데, 문서 편집은 문서 번호와 고친 사람만 있으면 되고, 댓글은 댓글 번호와 멘션된 사람 목록이 필요하고, 공유는 받는 사람과 권한 등급이 필요했습니다. 칸을 계속 더하다 보니 한 줄에 스무 칸이 생겼고 그중 열여섯 칸은 늘 비어 있었습니다. 기능이 하나 붙을 때마다 칸을 더하는 작업이 다시 예약됐습니다.
NoSQL 은 이 지점에서 전제를 하나 내려놓습니다. 모든 기록이 같은 모양이어야 한다는 전제입니다. 기록마다 들어 있는 항목이 달라도 되게 하면 칸을 더하는 작업 자체가 사라집니다. 대신 기록끼리 이어 주는 일은 데이터베이스가 아니라 프로그램이 맡습니다.
해결하는 문제
풀어 주는 문제는 넷이고, 계열마다 맡는 문제가 다릅니다.
- 항목이 제각각인 데이터. 문서형 계열은 기록 하나를 통째로 한 덩어리로 저장합니다. 앞의 활동 기록이라면 편집 기록과 댓글 기록이 서로 다른 항목을 들고 나란히 들어가고, 새 기능이 붙어도 그 기능의 기록만 새 항목을 달고 들어옵니다. 다른 기록을 고칠 일이 없습니다.
- 한 대에 담기지 않는 양. 여러 대에 나눠 담는 샤딩이 제품 안에 들어 있어서, 서버를 늘리면 데이터가 자동으로 나뉩니다. 표를 맞춰 읽지 않는 구조라 조각이 늘어도 읽는 방식이 복잡해지지 않습니다.
- 같은 값을 아주 빠르게 자주 꺼내야 하는 경우. 키-값 저장소는 열쇠 하나에 값 하나를 매달아 두고 열쇠로만 꺼냅니다. 로그인 상태나 자주 쓰는 계산 결과를 잠깐 얹어 두는 자리입니다.
- 의미가 비슷한 것을 찾아야 하는 경우. 벡터 데이터베이스는 문장의 뜻을 숫자 목록으로 바꿔 저장하고 글자가 아니라 의미로 찾습니다. "환불 어떻게 하나요" 와 "돈 돌려받고 싶어요" 를 같은 질문으로 묶는 검색이 여기서 나옵니다.
값을 내주는 대가가 있습니다. 여러 작업을 한 덩어리로 묶어 전부 성공하거나 전부 없던 일이 되게 만드는 트랜잭션이 관계형만큼 강하지 않은 제품이 많습니다. 여러 대에 흩어진 데이터를 한 묶음으로 잠그는 일이 어렵기 때문입니다. 값을 방금 고쳤는데 다른 서버에서 읽으면 예전 값이 잠깐 보이는 경우도 있습니다.
대안
먼저 볼 대안은 지금 쓰는 관계형 데이터베이스입니다. 표 모양이 정해진 계열이지만 요즘 제품들은 칸 하나에 자유로운 모양의 덩어리를 통째로 넣는 기능을 갖고 있어서, 기록마다 항목이 다른 데이터는 그 칸에 담으면 됩니다. 활동 기록 스무 칸 문제는 대개 여기서 끝납니다. 계정과 결제처럼 정확해야 하는 데이터는 표에 그대로 두고 쓸 수 있다는 점이 큽니다.
양이 문제라면 순서가 있습니다. 읽기 요청이 많으면 복사본을 몇 대 두어 읽기를 나눠 보내고, 자주 쓰는 계산 결과는 키-값 저장소에 잠깐 얹어 둡니다. 여기까지로 버티는 서비스가 생각보다 많습니다. 그래도 한 대에 안 들어갈 만큼 커진 뒤에 계열을 바꿉니다. 수백만 건 규모에서 미리 확장성을 걱정해 옮기면, 아직 오지 않은 부담을 피하려다 SQL 문장 하나로 끝나던 조회를 코드 여러 줄로 바꾸게 됩니다.
고를 때는 데이터의 모양이 아니라 꺼내는 방식을 봅니다. 한 화면에서 항상 한 덩어리를 통째로 꺼낸다면 문서형이 맞고, 여러 조건을 걸어 이리저리 맞춰 봐야 한다면 표 쪽이 맞습니다. 한 시스템에 둘을 함께 쓰는 경우도 흔합니다.
실무 용례
"이건 스키마가 계속 바뀔 것 같은데 NoSQL 로 갈까요?"
기록마다 항목이 달라질 데이터를 표에 담기 부담스럽다는 제안입니다.
"지금 규모에서는 관계형으로 충분해요. JSON 칼럼으로 받으면 됩니다."
계열을 바꾸지 말고 기존 표의 한 칸에 자유로운 덩어리를 담자는 말입니다.
"NoSQL 이라 조인이 없어서 이 화면은 질의가 네 번 나갑니다."
기록끼리 잇는 일을 프로그램이 하다 보니 요청이 여러 번으로 나뉜다는 뜻입니다.
페이지덱은 활동 기록만 문서형으로 옮겼습니다. 태오가 스무 칸짜리 표를 없애고 기록 하나를 통째로 넣자 새 기능이 붙어도 스키마를 고치는 작업이 따라붙지 않았습니다. 스키마는 어떤 표가 있고 표마다 어떤 칸이 있는지 적어 둔 설계도입니다.
회원과 결제는 옮기지 않았습니다. 수아가 청구 내역을 확인할 때 회사별, 기간별, 플랜별로 조건을 바꿔 가며 물어보는데, 이런 조회는 표 쪽이 압도적으로 편하기 때문입니다. 두 계열을 한 서비스 안에 나눠 쓰는 이 모양이 실무에서 가장 흔합니다.
흔한 오해
이름 때문에 SQL 을 안 쓰는 계열로 읽는 경우가 많습니다. 앞에 붙은 부정어가 질의 언어를 거부한다는 뜻처럼 보이기 때문입니다. 실제로 이 이름은 표 구조에만 매이지 않는다는 뜻에 가깝고, 요즘 제품들은 SQL 과 비슷한 질의 언어를 따로 제공합니다. 이 오해를 안고 가면 조회가 단순할 것이라 기대하고 옮겼다가, 표에서 한 문장이던 통계 질의를 코드로 다시 짜게 됩니다.
스키마가 아예 없다는 오해도 흔합니다. 데이터를 넣기 전에 칸을 정해 두지 않으니 없는 것처럼 보입니다. 사라진 것이 아니라 코드로 옮겨 간 것입니다. 어떤 항목이 들어 있는지 아는 쪽이 데이터베이스에서 프로그램으로 바뀌었을 뿐이고, 그래서 항목 이름을 한 군데에서 바꾸면 예전 모양으로 저장된 기록을 읽는 코드가 조용히 깨집니다. 검사해 주던 쪽이 없어졌으니 그 검사를 팀이 직접 해야 합니다.
자주 헷갈리는 용어
| 용어 | 어떻게 담는가 | NoSQL 과의 차이 |
|---|---|---|
| 관계형 데이터베이스 | 행과 열이 있는 표에 담고 표끼리 값으로 이어 둠 | 기록을 잇는 일을 데이터베이스가 맡습니다. 조건을 이리저리 바꿔 조회하는 일에 강한 대신 구조를 미리 정해야 합니다 |
같이 보면 좋은 페이지
- 데이터베이스
계열을 고르는 일이 전체 그림의 어디쯤인지 먼저 봅니다
- 관계형 데이터베이스
대부분의 서비스가 기본값으로 삼는 반대편 계열입니다
마지막 업데이트 2026-09-16