데이터 모델링은 지정된 데이터베이스에서 애플리케이션이 데이터를 저장하는 방법을 설계하는 프로세스입니다. DynamoDB와 같은 NoSQL 데이터베이스를 사용하는 데이터 모델링은 관계형 데이터베이스를 사용하는 모델링과 다릅니다. 관계형 데이터베이스는 유연성을 위해 구축되었으며, 분석 애플리케이션에 매우 적합합니다. 관계형 데이터 모델링에서는 엔터티에서 먼저 시작합니다. 정규화된 관계형 모델이 있으면 애플리케이션에 필요한 모든 쿼리 패턴을 충족시킬 수 있습니다.

NoSQL(비관계형) 데이터베이스는 유연성이 아니라, 속도 및 확장성을 위해 설계되었습니다. 확장할 경우 관계형 데이터베이스 성능이 저하될 수 있지만, DynamoDB와 같은 수평 확장 데이터베이스는 어떤 규모에서든 일관된 성능을 제공합니다. 일부 DynamoDB 사용자는 100TB보다 큰 테이블을 가지고 있으며, 해당 테이블의 읽기 및 쓰기 성능은 케이블 크기가 1GB 미만일 때와 같습니다.

DynamoDB와 같은 NoSQL 데이터베이스에서 최상의 결과를 얻으려면 일반 관계형 데이터베이스에서 사고의 전환이 필요합니다. DynamoDB에서 데이터를 모델링하는 경우 다음 모범 사례를 사용합니다.

1. 액세스 패턴에 집중
어떤 종류의 데이터 모델링을 수행하든, 애플리케이션에서 서로 다른 오브젝트나 엔터티 및 이들의 연결 방식이나 엔터티 간의 관계를 설명하는 엔터티-관계 다이어그램에서 시작합니다.

관계형 데이터베이스에서 테이블에 직접 엔터티를 배치하고 외부 키를 사용하여 관계를 지정합니다. 데이터 테이블을 정의한 후에 관계형 데이터베이스는 필요한 형태로 데이터를 반환하도록 유연한 쿼리 언어를 제공합니다.

DynamoDB에서 테이블을 모델링하기 전에 액세스 패턴을 검토합니다. NoSQL 데이터베이스는 유연성이 아니라, 속도에 초점을 맞춥니다. 먼저, 데이터에 액세스하는 방법을 질문하고, 액세스하는 형태로 데이터를 모델링합니다.

DynamoDB 테이블을 설계하기 전에 애플리케이션에서 데이터를 읽고 쓸 때 필요한 모든 사항을 문서화합니다. 애플리케이션에서 모든 흐름을 철저하게 검토해야 합니다. 액세스 패턴에 맞게 테이블을 최적화하기 때문입니다.

2. DynamoDB에 대한 요청 수 최적화
애플리케이션의 액세스 패턴 요구 사항을 문서화한 후에는 테이블을 설계할 준비가 되었습니다. 각 액세스 패턴에 대해 DynamoDB로의 요청 수를 최소화하도록 테이블을 설계해야 합니다. 각 액세스 패턴은 DynamoDB에 하나의 요청만 요구하는 것이 이상적입니다. 네트워크 요청이 느리고 이로 인해 애플리케이션에서 수행하는 네트워크 요청 수가 제한되기 때문입니다.

DynamoDB에 대한 요청 수를 최적화하려면 몇 가지 핵심 개념을 이해해야 합니다.

기본 키
보조 인덱스
트랜잭션

3. 관계형 모델에 현혹되지 않기
DynamoDB를 처음 접하는 사람들은 종종 비관계형 DynamoDB에 기반한 관계형 모델을 구현하려고 합니다. 그렇게 하면 대부분의 DynamoDB 이점을 놓칠 수 있습니다.

DynamoDB에서 시도하는 가장 일반적인 안티 패턴(반복되는 문제에 대한 비효율적인 응답)은 다음과 같습니다.

  •  정규화: 관계형 데이터베이스에서는 데이터를 정규화하여 데이터 중복성 및 스토리지 공간을 줄인 후에 조인을 사용하여 서로 다른 여러 테이블을 결합합니다. 하지만 대규모 조인은 작업이 느리고 비용도 많이 듭니다. DynamoDB에서는 테이블이 커지면 조인으로 인해 속도가 느려지기 때문에 조인을 허용하지 않습니다.
  • 테이블당 하나의 데이터 유형: DynamoDB 테이블은 종종 하나의 테이블에서 여러 유형의 데이터를 포함하기도 합니다. 여기에서 사용하는 예제에서는 하나의 테이블에 User, Game 및 UserGameMapping 엔터티를 사용합니다. 관계형 데이터베이스에서는 이를 3개의 다른 테이블로 모델링합니다.
  • 너무 많은 보조 인덱스: 종종 필요한 추가 액세스 패턴에 대해 보조 인덱스를 생성하기도 합니다. DynamoDB에는 스키마가 없으며, 이는 인덱스에도 적용됩니다. 속성에서 이러한 유연성을 활용하여 테이블의 여러 데이터 유형에서 하나의 보조 인덱스를 재사용합니다. 이를 인덱스 오버로드라고 합니다.

아래 단계에서는 엔터티-관계 다이어그램을 구축하고 액세스 패턴을 미리 매핑합니다. 이는 DynamoDB를 사용할 때 항상 첫 번째 단계여야 합니다. 그리고 후속 모듈에서는 테이블 설계에서 이러한 액세스 패턴을 구현합니다.

모듈 완료 시간: 20분


  • 1단계: 엔터티-관계 다이어그램 구축

    데이터 모델링 연습의 첫 번째 단계는 애플리케이션에서 엔터티를 표시하고 이를 상관시키는 방법을 표시하는 다이어그램을 구축하는 것입니다.

    여기 애플리케이션에서는 다음 엔터티를 사용합니다.
    • User
    • Game
    • UserGameMapping

    User 엔터티는 애플리케이션에서 사용자를 나타냅니다. 사용자는 여러 Game 엔터티를 생성할 수 있으며, 게임 제작자는 플레이하는 지도와 게임 시작 시점을 결정합니다. User는 여러 Game 엔터티를 생성할 수 있으므로, UserGame 사이의 일대다 관계가 존재합니다.

    마지막으로 Game은 여러 User를 포함하며, User는 시간이 지남에 따라 많은 여러 Game을 플레이할 수 있습니다. 따라서 UserGame 사이에 다대다 관계가 존재합니다. 그리고 UserGameMapping 엔터티로 이 관계를 나타낼 수 있습니다.

    이러한 엔터티와 관계를 염두에 두고, 엔터티-관계 다이어그램이 아래 표시됩니다.

    Module2-step1

    (확대하려면 클릭)

    Module2-step1
  • 2단계: 사용자 프로필 액세스 패턴 고려

     게임의 사용자는 사용자 프로파일을 생성해야 합니다. 이 프로필에는 사용자 이름, 아바타, 게임 통계 및 각 사용자에 대한 기타 정보와 같은 데이터가 포함됩니다. 게임은 사용자가 로그인하면 이 사용자 프로필을 표시합니다. 다른 사용자는 사용자 프로필을 보고 게임 통계 및 기타 세부 정보를 검토할 수 있습니다.

    사용자가 게임을 플레이하면 사용자가 플레이하는 게임 수, 사용자가 승리한 게임 수 및 사용자의 처치 수를 반영하도록 게임 통계가 업데이트됩니다.

    이 정보에 따라 3개의 액세스 패턴이 있습니다.

    •  사용자 프로필 생성(쓰기)
    •  사용자 프로필 업데이트(쓰기)
    • 사용자 프로필 가져오기(읽기)
  • 3단계: 사전 게임 액세스 패턴 고려

    여기서 사용하는 게임은 Battle Royale 게임입니다. 플레이어는 특정 지도에서 게임을 생성하고 다른 플레이어는 이 게임에 참여할 수 있습니다. 50명의 플레이어가 게임에 참여하면 게임이 시작되고 추가 플레이어는 참여할 수 없습니다.

    참여할 게임을 검색할 때 플레이어는 특정 지도를 플레이하고 싶어할 수 있습니다. 다른 플레이어는 지도에는 관심이 없고 모든 지도에서 열린 게임을 찾아보려고 합니다.

    이 정보에 따라 다음과 같은 7개의 액세스 패턴이 있습니다.

    • 게임 생성(쓰기)
    • 열린 게임 찾기(읽기)
    • 지도별 열린 게임 찾기(읽기)
    • 게임 보기(읽기)
    • 게임에서 사용자 보기(읽기)
    • 사용자의 게임 참여(쓰기)
    • 게임 시작(쓰기)
  • 4단계: 게임 내 및 게임 후 액세스 패턴

    마지막으로 게임 도중과 게임 이후에 액세스 패턴을 고려합니다.

    게임 중에 플레이어는 최후 생존을 목표로 다른 플레이어를 처치하려고 합니다. 애플리케이션에서는 게임 중에 각 플레이어의 처치 수 및 게임에서 플레이어가 생존한 시간을 추적합니다. 플레이어가 게임에서 최후 생존 3인 안에 들면 플레이어는 게임에서 골드, 실버 또는 브론즈 메달을 받습니다.

    나중에 자신이 플레이했거나 다른 플레이어가 플레이한 이전 게임을 검토하고 싶을 수도 있습니다.

    이 정보에 따라 3개의 액세스 패턴이 있습니다.

    • 사용자의 게임 업데이트(쓰기)
    • 게임 업데이트(쓰기)
    • 사용자의 모든 이전 게임 찾기(읽기)

    이제 게임의 모든 액세스 패턴을 매핑했습니다. 다음 모듈에서는 DynamoDB를 사용하여 이러한 액세스 패턴을 구현합니다.

    계획 단계에서는 몇 가지 반복이 나타날 수 있습니다. 애플리케이션에 필요한 액세스 패턴의 일반적인 아이디어에서 시작합니다. 테이블에서 기본 키, 보조 인덱스 및 속성을 매핑합니다. 시작 단계로 돌아가 모든 액세스 패턴을 충족하는지 확인합니다. 계획 단계가 완전하다고 확신하면 구현으로 진행합니다.