
이전 시간에 API Gateway와 Lambda를 활용하여 서버리스 API를 구축했습니다.
빠르고 저렴한 API 서버를 구축했다면, 다음은 바로 DB 설계입니다.
이번엔 AWS DynamoDB라는 서비스를 사용해 봤는데요, 제가 알고 있던 일반적인 NoSQL(MongoDB 등)과는 설계 방식이 달라서 조금 신기했습니다.
AWS DynamoDB를 사용하는 이유
제가 기획한 ‘바이블톡’의 프로토타입은 AI 페르소나와 실시간으로 롤플레잉 대화를 나누는 챗봇 서비스입니다. 서비스 특성상 기존 데이터를 복잡하게 수정(Update)하는 작업보다는, 쉴 새 없이 쏟아지는 대용량 채팅 데이터를 지연 없이 빠르게 읽고 쓰는(Read/Write) 성능이 훨씬 중요했습니다.
따라서 DB 아키텍처를 설계할 때, 우리에게 익숙한 MySQL이나 PostgreSQL 같은 RDBMS보다는 대규모 트래픽 처리에 유리한 NoSQL 기반의 데이터베이스가 적합하다고 판단했습니다.
하지만, 그렇다고 해서 모든 데이터를 NoSQL에 넣는 것은 정답은 아니라고 생각합니다. 결과적으로 데이터의 성격에 맞춰 결제나 유저 정보처럼 무결성이 중요한 데이터는 Amazon RDS(RDBMS)에 두고, 쌓이는 대화 로그만 Amazon DynamoDB(NoSQL)로 분리 하는 ‘하이브리드(Hybrid) DB 아키텍처’를 채택했습니다.
이번 포스팅에서는 그중에서도 왜 ‘채팅 로그’ 처리에서 NoSQL을 선택하게 되었는지,
그리고 직접 겪어본 DynamoDB는 기존 NoSQL과 무엇이 달랐는지 그 고민의 과정을 다뤄보겠습니다.
1. RDBMS와 NoSQL, 그리고 DynamoDB란?
DB 아키텍처를 결정하기 위해 먼저 우리가 사용할 도구들의 정확한 특성을 알아야 합니다.
RDBMS와 NoSQL의 차이는 IT 개발자라면 대부분 아는 내용이겠지만,
다이나모DB 개념을 알아보는 김에 한 번 정리해 보았습니다.
– RDBMS, 관계형 데이터베이스
우리가 흔히 아는 MySQL, Oracle 등이 여기에 속합니다.
엑셀 표처럼 정해진 형식(스키마)에 맞춰 데이터를 엄격하게 저장합니다.
데이터의 중복을 없애고(정규화), 여러 테이블을 연걸(Join) 해서 다룰 수 있으며, 돈이 오가는 결제처럼 ‘데이터의 무결성(정확성)’이 생명일 때 반드시 써야 하는 DB입니다.
– NoSQL, 비관계형 데이터베이스
RDBMS의 엄격한 규칙을 깬 자유로운 DB입니다.
정해진 스키마가 없어서(Schemaless) 데이터 형태가 제각각이어도 그냥 밀어 넣을 수 있습니다.
데이터 간의 복잡한 관계(Join)를 포기한 대신, ‘엄청난 속도의 읽기/쓰기와 무한대에 가까운 수평 확장성’을 얻은 DB입니다.
– NoSQL DynamoDB
위에서 말한 NoSQL DB를 AWS에서 ‘완전 관리형(Serverless)’으로 제공하는 서비스입니다.
개발자가 서버 용량을 늘리거나 디스크를 추가할 필요 없이, 트래픽이 1명일 때나 100만 명일 때나 일관되게 10ms(밀리초) 미만의 초고속 응답 속도를 보장해 주는 서비스입니다.
2. 챗봇 대화 로그에 RDBMS는 부적합한가?
위에서도 살짝 언급하고 지나갔지만, 조금만 더 상세하게 정리해 보겠습니다.
유저의 프로필이나 결제 내역은 무결성이 중요하므로 당연히 RDS(RDBMS)에 저장하는 게 맞습니다. 하지만 ‘채팅 로그’는 성격이 완전히 다릅니다.
- 데이터의 폭발적인 증가 속도 (성능 문제): 채팅은 쓰기(Write) 작업이 엄청나게 발생합니다. RDBMS는 데이터가 수백만, 수천만 건으로 쌓이면 인덱스가 비대해져 쓰기/읽기 성능이 급격히 저하됩니다. 실시간 대화가 생명인 챗봇에서 DB 응답이 느려지면 치명적입니다.
- 비정형 데이터의 유연성 (스키마 문제): AI 챗봇 서비스는 MVP 테스트 과정에서 대화 메타데이터(예: AI의 감정 상태 파라미터, 사용자의 선택지 등) 필드가 수시로 추가되거나 변경될 수 있습니다. RDBMS에서 매번 ALTER TABLE을 수행하며 스키마를 변경하는 것은 운영상 엄청난 리스크이자 병목입니다.
그렇기 때문에 스키마리스 구조로 유연성을 가지면서도 쓰기/읽기 속도가 압도적인 NoSQL, 그 중에서도 DynamoDB를 채팅 로그 전용 DB로 결정했습니다.
3. 일반적인 NoSQL과는 다른 DynamoDB만의 모델링
RDBMS가 아닌 NoSQL을 쓰기로 했다면, 우리에게 친숙한 MongoDB 같은 문서형(Document) DB를 쓰는 것이 일반적일 수 있습니다. 저 역시 처음엔 그럴 생각이었지만, 개념적으로만 알고 있던 DynamoDB를 직접 만져보고는 생각이 달라졌습니다.
MongoDB는 스키마가 없을 뿐, 사실상 RDBMS처럼 내가 원하는 필드(컬럼)를 조건으로 자유롭게 검색(Query)할 수 있습니다. 분명 편리한 기능이지만, 데이터가 폭발적으로 늘어나면 결국 이런 복잡한 검색 조건들이 응답 속도를 떨어뜨리는 원인이 될 수 있습니다.
반면 DynamoDB는 애초에 속도 저하의 원인이 되는 이 ‘검색의 자유도’를 철저하게 포기한 철학을 가지고 있습니다. 대신 데이터가 1억 건이든 100억 건이든 무조건 10ms 이하의 검색 속도를 보장하죠.
DynamoDB는 “데이터를 정확히 어떻게 조회할 것인가?(Access Pattern)”를 개발 시작 전부터 완벽하게 정의하고, 오직 그 패턴으로만 데이터를 찾을 수 있게 강제합니다.
바이블톡 챗봇의 가장 핵심적인 데이터 접근 패턴(Access Pattern)은 딱 하나였습니다.
“특정 채팅방(Room)의 이전 대화 내역을 ‘시간순’으로 쫙 긁어온다.”
이 하나의 패턴을 가장 빠르게 처리하기 위해, 일반적인 DB에는 없는 DynamoDB만의 독특한 핵심 무기인 파티션 키(Partition Key, PK)와 정렬 키(Sort Key, SK) 개념을 도입해야 합니다.
- 파티션 키(PK): 데이터를 거대한 서랍장에 물리적으로 나누어 담는 기준표입니다.
(예: “이 데이터는 어느 채팅방의 데이터인가?”) - 정렬 키(SK): 같은 서랍장(PK) 안에서 데이터를 순서대로 줄 세우는 기준입니다.
(예: “메시지가 언제 작성되었는가?”)
이 개념으로 아래와 같이 설계를 해보았습니다.
- 테이블명: BibleTalk_ChatLogs
- 파티션 키 (PK): Room ID (채팅방 고유 ID)
- 정렬 키 (SK): CreatedAt (메시지 생성 타임스탬프)
이렇게 설계하면 데이터는 다음과 같이 저장됩니다.
| PK (RoomID) | SK (CreatedAt) | Sender | Message | Ai_Emotion (선택) |
room_101 | 2026-05-01T10:00:01 | User | “안녕, 고민이 있어서 왔어.” | |
room_101 | 2026-05-01T10:00:03 | AI | “어떤 고민이신가요? 들어줄게요.” | empathy |
room_999 | 2026-05-01T10:01:20 | User | “오늘 날씨 어때?” |
예시로 101번 방에 들어갔을 때 조건절에 복잡하게 쿼리를 짤 필요 없이,
그저 “서랍장 이름이 room_101인 것을 열어서, CreateAt 순서대로 줘”라고 요청하면 끝납니다.
이 방식 덕분에 데이터가 아무리 쌓여도 10ms 이하의 속도가 보장되는 것입니다.
4. AWS DynamoDB 생성 방법
이론적인 설계를 마쳤으니, 이제 실제로 AWS 콘솔에 접속하여 BibleTalk_ChatLogs 테이블을 구축해 보겠습니다. 관계형 DB처럼 복잡한 쿼리문을 칠 필요 없이, 마우스 클릭 몇 번이면 끝납니다.
Step 1. 테이블 생성 및 이름 지정
AWS DynamoDB 콘솔에 접속하여 [테이블 생성(Create table)] 버튼을 클릭합니다.


Step 2. 테이블 세부 정보 입력
앞서 설계한 접근 패턴에 맞춰 테이블 이름, 키를 지정합니다.
이 설정이 DynamoDB 성능의 90%를 결정합니다.
- 파티션 키(Partition key): RoomID를 입력하고, 데이터 타입은 문자열(String)로 선택합니다.
- 정렬 키(Sort key): 활성화한 뒤 CreateAt을 입력하고, 데이터 타입 역시 문자열(String)로 선택합니다.
Step 3. 테이블 설정 (기본값 vs 사용자 지정) 키 입력란 바로 아래를 보면 ‘테이블 설정(Table settings)’ 항목이 있습니다. 여기서 AWS가 추천하는 ‘기본 설정(Default settings)’을 그대로 쓰면 편하겠지만, 저는 ‘사용자 지정 설정(Customize settings)’을 선택했습니다.
이유는 초기 스타트업 MVP에 가장 알맞은 과금 모델(용량 모드)을 직접 선택하기 위해서입니다.

Step 3. MVP를 위한 과금 모델: 온디맨드(On-Demand)
아직 트래픽이 얼마나 어떻게 발생할지 모르는 상황이라, 여러 서비스 후기들을 참고해서 커스터마이징을 시도하게 되었습니다. (콘솔에 검색하면 블로그, 후기 등등 많은 정보가 나옵니다.)
사용자 지정 설정으로 진입하면, 테이블의 읽기/쓰기 용량을 어떻게 할당할지 묻는 ‘용량 모드(Capacity Mode)’ 설정이 나옵니다. DynamoDB는 두 가지 과금 방식을 제공합니다.
- 온디맨드(On-Demand): 설정 없이 쓴 만큼만 낸다
(갑작스러운 트래픽 스파이크에 알아서 대응함). - 프로비저닝됨(Provisioned): 초당 몇 번 읽고 쓸지 미리 정해두고 월정액처럼 내는 방식
(트래픽이 일정할 때 저렴함).

저는 ‘온디맨드(On-Demand)’ 모드를 선택했습니다.
초기 스타트업은 내일 트래픽이 0명일지, 마케팅이 터져서 1만 명이 들어올지 전혀 예측할 수 없습니다.
쓰지도 않을 용량을 미리 결제해두는 것은 리소스 낭비이며, 반대로 핫타임에 용량이 부족해 DB가 뻗어버리면 고객을 영영 잃게 됩니다.
온디맨드는 단가는 미세하게 높을지언정 이 인프라 리스크를 완벽하게 없애준다고 생각합니다.
마치며: 다이나모디비
모든 데이터를 DynamoDB에 넣는 것은 정답이 아닙니다. 결제의 무결성은 RDS가, 대화 로그의 확장성은 DynamoDB가 책임지는 하이브리드 구조가 현재 바이블톡 비즈니스에 가장 적합한 Trade-off였습니다.
인프라 아키텍처에 만능의 정답은 없으며, 데이터의 특성을 분석하여 적재적소에 올바른 목적의 DB를 조합해 내는 것이 백엔드 아키텍트의 역할임을 깊이 체감했습니다.
다음 글에서는 비즈니스 로직을 처리하는 Lambda와 무거운 AI 모델을 추론하는 ECS를 어떻게, 왜 분리했는지 다루어 보겠습니다.
답글 남기기