HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤩
개발
/데이터베이스(Database)/
Database
Database
/
DynamoDB

DynamoDB

SDK테이블 정의데이터 CRUD 종류대용량 데이터 처리조회GSI를 이용한 조회보조 인덱스글로벌 보조 인덱스코틀린에서 정의하기로컬 보조 인덱스
AMAZON DynamoDB 키 디자인 패턴
 
분산처리를 위해서 만들어진 NoSql - DynamoDB
  • 태생적으로 분산 처리를 고려하여 만든 Database
  • 데이터의 규모와 관계없이 일관되게, 수 밀리초 미만의 응답시간, 사실상 무제한의 처리량
  • 관계형 데이터베이스의 장점인 보조인덱스와 트랜젝션 제공함
  • 백업 복원도 쉬움
AMAZON DynamoDB 키 디자인 패턴
[ AWS DOCS ] Programming with Java 2.x, Supported interfaces, Amazon DynamoDB
[ AWS DOCS ] Best practices for designing and architecting with DynamoDB
[ AWS Docs ] DynamoDB local 사용 참고 사항, 컴퓨터에 로컬로 DynamoDB 배포
 

SDK

  • AWS SDK for Java 2.x (High level api) : DynamoDBEnhancedClient API, Use advanced mapping features
  • DynamoDbBean 어노테이션 사용하기
    • [Blog ] Using Dynamodb with Kotlin + Spring Boot
    • [ Git issue ] DynamoDB Enhanced Client support for Immutable objects
    • [ AWS Docs ] Work with nested attributes
  • AWS SDK for Java 2.x (Low level api) : DynamoDBClient

테이블 정의

  • primary key 를 정해주어야 함. 고유한 값

데이터 CRUD 종류

AttributeValue 종류
[ AWS Docs ] Working with items and attributes
  • GetItem : partition key 와 sort key를 명시해야 함(해당 테이블에 sort key가 있다면) 아이템 한개 가져오기
  • BatchGetItem : Read up to 100 items from one or more tables
  • Query : 특정 partition key를 갖고 있는 아이템들을 조회
  • GetItem, Query, Scan, BatchGetItem
notion image
notion image

대용량 데이터 처리

  • scale up
  • CPU 분산(Read replica)
  • 캐쉬 계층
  • 하나의 물리적 서버에서 처리하기엔 점점 힘듦을 느끼게 됨
  • 샤드? 그러나 샤드를 하게되면 운영에서 많은 어려움을 마주하게됨. 백업 복원도 어려워지고
 

조회

[ AWS Docs ] Working with scans in DynamoDB, 표현식 및 조건 사용, Comparison operator and function reference
  • Query : PartitionKey가 필요, GSI(PK + optional sortkey)를 이용해서도 가능함
  • scan : 풀 스캔

GSI를 이용한 조회

// 기본 GSI 조회 QueryConditional.keyEqualTo { key -> key.partitionValue(email) } // GSI + SortKey 조건 QueryConditional.sortBeginsWith { key -> key.partitionValue(email).sortValue(status) } QueryConditional.sortBetween { key -> key.partitionValue(email).sortValue(startDate, endDate) }
 

보조 인덱스

Improving data access with secondary indexes in DynamoDB

글로벌 보조 인덱스

DynamoDB 에서 글로벌 보조 인덱스 사용
로컬 보조 인덱스(LSI)는 추가 비용이 들지 않는 반면에, 얘는 WCUs가 2배가 됨. base table에다가 쓰고, global secondary index를 위한 테이블에도 한번 더 써야하기 때문에
GameScores 라는 테이블이 있을 때, 파티션 키(UserId), 정렬 키(GameTitle)이라고 하면
notion image
키 속성(UserId, GameTitle)을 지정한 쿼리는 매우 효율적. 그러나 애플리케이션에서 GameTitle 만을 토대로 GameScores 에서 데이터를 검색해야 할 경우에는 Scan 작업을 사용해야 함(비효율적)
키가 아닌 속성에 대한 쿼리 속도를 높이기 위해 글로벌 보조 인덱스를 만들 수 있고 글로벌 보조 인덱스는 기본 테이블의 속성 중 일부를 포함하지만 테이블과 다른 기본 키를 기준으로 구성.
예로, 파티션 키가 GameTitle 이고 정렬 키가 TopScore 인 GameTitleIndex 라는 글로벌 보조 인덱스를 생성할 수 있음

코틀린에서 정의하기

@DynamoDbBean data class Currency( // KSUID @get:DynamoDbAttribute("id") var id: String = "", // Primary Key // pk-currencyCode-contryCode-sk-timestamp @get:DynamoDbPartitionKey @get:DynamoDbAttribute("PK") var pk: String = "", @get:DynamoDbAttribute("currency_code") @get:DynamoDbSecondaryPartitionKey(indexNames = ["gsi-pk-currency-code-sk-timestamp"]) var currencyCode: String = "", @get:DynamoDbAttribute("contry_code") var contryCode: String = "", @get:DynamoDbAttribute("value") var value: BigDecimal = BigDecimal.ZERO, @get:DynamoDbSortKey @get:DynamoDbAttribute("timestamp") @get:DynamoDbSecondarySortKey(indexNames = ["gsi-pk-currency-code-sk-timestamp"]) var timestamp: String = "" )
  • DynamoDB의 엔티티 클래스에는 @DynamoDbBean을 명시한다.
  • 각 애트리뷰트와 필드를 맵핑하기 위한 정보로서 @DynamoDbAttribute을 명시할 수 있다. 이를 통해 물리적인 애트리뷰트의 이름과 필드명을 다르게 할 수 있다.
  • Primary Key(PK)의 Partition Key(PK)에 해당하는 필드에는 @DynamoDbPartitionKey를 명시한다. 마찬가지로 Primary Key(PK)의 Sort Key(SK)에 해당하는 필드에는 @DynamoDbSortKey를 명시한다.
  • GSI에는 앞서 PK와 유사하게 @DynamoDbSecondaryPartitionKey와 @DynamoDbSecondarySortKey를 명시한다.
  • LSI 에는 @DynamoDbSecondarySortKey 와 인덱스 이름을 명시

로컬 보조 인덱스

DynamoDB의 로컬 보조 인덱스
notion image
PartitionKey가 ForumName, Subject가 sortKey인 상태에서 아래와 같은 데이터 액세스 패턴이 필요할때
  • 보기 및 회신 횟수가 가장 많은 포럼 스레드
  • 특정 포럼에서 메시지 수가 가장 많은 스레드
  • 특정 기간 동안 특정 포럼에 게시된 스레드 수
다른 인덱스가 없다면 테이블 전체를 Scan 해야 함
하지만, Replies 또는 LastPostDateTime 같이 키가 아닌 속성에 하나 이상의 LocalSecondaryIndex 를 지정 가능 → 로컬 보조 인덱스의 데이터는 기본 테이블과 동일한 파티션 키를 기준으로 구성되지만, 다른 정렬 키를 사용 → Queryt작업에서 정렬키로 LastPostDateTime을 사용하여 데이터를 빠르게 찾을 수 있음
 
로컬인덱스는 바로바로 동기적으로 작업되고 글로벌인덱스는 비동기적으로 값이 들어가고.
로컬보조인덱스는 테이블 만들때 만들어야 하고 글로벌보조인덱스는 중간에 만들수 있음
scan은 풀 서치고 query는 인덱스 사용해서 데이터가져오는 거고