14B. DynamoDB에 맞는 데이터 구조 설계하기
14B. DynamoDB에 맞는 데이터 구조 설계하기 관련
DynamoDB는 MySQL, Oracle, SQL Server 등의 RDBMS와는 특성이 다릅니다. 프로젝트 혹은 제품에서 요구하는 기능이 있을 것인데, 그중 DynamoDB에서 효율적으로 처리할 수 있는 요구사항은 DynamoDB에서 처리합니다. RDBMS에서 효율적으로 처리할 수 있는 부분까지 DynamoDB로 이전할 필요는 없습니다.
DynamoDB는 RDBMS에 비해 데이터 구조를 자유롭게 저장할 수 있으므로 이 부분을 적극 활용합니다. 또한, 데이터 개수가 많고, 용량이 커서 서버 한대로 처리할 수 없을 때 유용하게 사용할 수 있습니다. RDBMS에서는 서버를 대용량 데이터를 분할하여 처리하기가 상당히 어렵습니다.
이번에는 애니팡이나 쿠키런과 같은 모바일 게임의 DB를 설계해보겠습니다. 이러한 게임의 핵심 요구사항은 다음과 같습니다(로그인, 유저 및 친구관리, 선물, 상점 기능은 생략하겠습니다).
- 주간 전체순위 산출
- 주간 친구순위 산출
- 개인 최근 점수 목록 조회
- 개인 최고기록 조회
완벽하게 제품화할 정도로 설계를 하자면 내용도 많아지고 복잡해지기 때문에 DynamoDB의 인덱스, 로컬 보조 인덱스, 글로벌 보조 인덱스를 활용하는 방법 위주로 간단하게 설계해보겠습니다. 게임을 할 때마다 서버에 점수를 전송하여 DB에 저장하고, 주간 전체순위, 주간 친구순위를 산출한다고 가정해보겠습니다.
먼저 주간 전체순위 산출을 위한 유저 순위 테이블(UsersLeaderboard
)의 구조입니다.
- Id: 숫자 형식이며 유저를 구분하는 유일한 값입니다.
- Name: 문자열 형식이며 유저의 이름을 저장합니다.
- TopScore: 숫자 형식이며 유저의 주간 최고점수를 저장합니다.
- Week: 문자열 형식이며 한 주를 저장합니다. 예) 2014-05-09,2014-05-15
UsersLeaderboard
유저 순위 테이블
키 이름(값 형식) | Id(Number) | Name(String) | TopScore(Number) | Week(String) |
---|---|---|---|---|
테이블 인덱스 | 해시 기본 키 | 범위 기본 키 | ||
로컬 보조 인덱스 | 해시 키 | 범위 키 | ||
글로벌 보조 인덱스 | 범위 키 | 해시 키 |
Id
를 해시 기본 키, Week
를 범위 기본 키로 설정한 테이블 인덱스로 개인 최근 점수 목록을 조회할 수 있습니다. Week
를 9999-12-31,9999-12-31보다 작은less than 조건으로 내림차순으로 정렬하면 됩니다. Id
를 해시 키, TopScore
를 범위 키로 설정한 로컬 보조 인덱스로 개인 최고기록을 조회할 수 있습니다. TopScore
를 99999보다 작은less then 조건으로 내림차순 정렬하면 됩니다(최대점수는 99999라고 가정).
Week
를 해시 키, Top Score를 범위 키로 설정한 글로벌 보조 인덱스로 주간 전체순위를 산출할 수 있습니다. Week
를 2014-05-09,2014-05-15와 같은equal to 조건에 TopScore
를 99999보다 작은less than 조건으로 내림차순 정렬하면 됩니다.
이제 주간 친구순위 산출을 위한 친구 순위 테이블(FriendsLeaderboard
)의 구조입니다.
- Id: 숫자 형식이며 유저를 구분하는 유일한 값입니다.
- Name: 문자열 형식이며 유저의 이름을 저장합니다.
- Score: 숫자 형식이며 현재 유저가 획득한 점수를 저장합니다.
- FriendIdAndWeek: 문자열 형식이며 현재 유저의 친구
Id
와 한 주를 함께 저장합니다. 친구Id
가 2라면 2,2014-05-09,2014-05-15와 같은 형식입니다. 현재 유저가 게임을 플레이 할 때마다, 유저의 모든 친구Id
와 주를 이런 방식으로 점수와 함께 저장해야 합니다. 또한, 유저Id
가 1이라면 1,2014-05-09,2014-05-15와 같이 자기자신의 데이터도 저장합니다.
FriendsLeaderboard
친구 순위 테이블
키 이름(값 형식) | Id(Number) | Name(String) | Score(Number) | FriendIdAndWeek(String) |
---|---|---|---|---|
테이블 인덱스 | 해시 기본 키 | 범위 기본 키 | ||
글로벌 보조 인덱스 | 범위 키 | 해시 키 |
FriendIdAndWeek
를 해시 키, Score
를 범위 키로 설정한 글로벌 보조 인덱스로 주간 친구순위를 산출할 수 있습니다. 조회하고 싶은 Id
가 2라면 FriendIdAndWeek
를 2,2014-05-09,2014-05-15와 같은equal to 조건에 Score
를 99999보다 작은less than 조건으로 내림차순 정렬하면 됩니다. 이렇게 하면 내 친구들의 Id
와 점수를 조회할 수 있습니다.
이런 방법으로 DynamoDB에 점수 데이터를 저장하면 늘어나는 유저의 숫자와 상관없이 순위를 산출할 수 있습니다. 기존에 순위를 구할 때에는 Redis 같은 인 메모리 데이터베이스에서 제공하는 Sorted Set 자료 구조로 순위를 산출했지만 유저가 많이 늘어나서 메모리 용량을 벗어나는 경우 개발 및 운영을 하기가 상당히 까다로웠습니다. DynamoDB는 데이터가 늘어나면 알아서 대응을 해줘서 용량에 대해 신경 쓸 필요가 없고 쿼리 속도 또한, 빨라서 상당히 편리합니다.