본문 바로가기
미분류

Dynamodb Secondary Index

by 혜리루 2021. 5. 9.

1. 서론

dynamodb는 사용한 만큼 비용을 지불합니다.

때문에 가능한 적은 양의 데이터를 쿼리하는 것이 유리한데요, dynamodb도 RDB처럼 테이블을 생성할때 설정한 primary key를 이용해 빠르게 item에 접근할 수 있습니다.

 

하지만 하나의 key만으로는 다양한 어플리케이션의 요구사항을 만족시키기 어렵기 때문에 dynamodb를 이용할때는 대부분 secondary index를 생성하여 사용합니다.

 

2.secondary index

secondary index란 대체(altanative) key와 테이블의 다른 attribute들의 subset을 포함하는 데이터 구조입니다.

테이블과 마찬가지로 index에 쿼리를 해서 데이터를 가져올 수 있습니다.

 

secondary index는 primary key와 다르게 여러개를 만드는 것이 가능하며, 때문에 여러가지 쿼리패턴을 사용할 수 있습니다.

secondary index를 만들 때는 기본적으로 다음의 세가지가 필요합니다.

 

1) base table (기본이 되는 테이블)

2) altanative key ( partition key + sort key)

3) project하거나 복제할 attribute

 

base table의 데이터를 수정할때마다 index의 데이터 또한 자동으로 수정됩니다.

 

 

 

 

3. secondary index의 종류

secondary index에는 크게 두가지 종류가 있습니다.

각각의 특징이 다르기 때문에 두 index의 특징을 숙지하고 필요한 상황에 쓰는 것이 좋겠습니다.

 

1) global secondary index (GSI)

 

 - pk와 sk가 base table의 key들과 달라도 됩니다.

 - 데이터가 base table과 다른 partition에 저장됩니다.

 - base table과 따로 scale 됩니다.

 - 쿼리를 할때 모든 partition에 대해서 하기 때문에 global이라고 부릅니다.

 - 20개까지 생성 가능합니다.

 

 

2) local secondary index (LSI)

 

 - base table과 같은 partition key, 다른 sort key를 사용합니다.

 - partition key에 해당하는 하나의 partition에 대해서만 쿼리하기 때문에 local이라고 부릅니다.

 - 5개까지 생성 가능합니다.

 

비교 표

 

 

4. secondary index를 만들때 결정해야 할 것

 

1) index의 타입 (GSI or LSI)

2) index명.

  테이블과 같은 naming rule을 적용합니다. 한 테이블에 대해서 index의 이름은 유일해야합니다.

3) key schema

  key는 string, number, binary중 하나여야합니다.

 3-1) GSI : simple key(partition key 한개)가 허용됩니다. base table의 어떤 attribute도 가능합니다.

 3-2) LSI: partition key - base table의 pk와 같은 key를 사용합니다. sort key - partition key가 아닌 다른 attribute를 사용합니다.

4) project할 key를 제외한 다른 attribute ( key는 자동으로 project합니다.)

5) provisioned throughput setting

 5-1) GSI: 꼭 명시해야합니다. base table과 독립적으로 적용됩니다.

 5-2) LSI: 명시하지 않아도 됩니다. base table의 provisioned throughput setting을 사용합니다.

 

5. 그외

1) DescribeTable 명령을 하면 index의 이름, 사이즈, 아이템 개수를 보여줍니다. 실시간은 아니고 6시간 마자 업데이트됩니다.

2) secondary index의 데이터를 가져올때는 table명, index명, 가져올 attribute, filter를 명시합니다

3) table을 삭제하면 index도 함께 삭제됩니다.

 

6. GSI 사용하기

위의 GameScores 테이블에서 pk는 Userid, sk는 GameTitle입니다.

각 user를 기준으로 데이터를 보기는 쉽지만, 예를 들어서 각 게임에서 top score ranker를 찾고싶다면

모든 데이터에 대해서 scan해야 하기 때문에 시간도 오래 걸리고 비용이 아주 많이 나올 것입니다.

 

 

6.1 gsi 생성하기

위의 경우에는 이 처럼 GSI를 생성해 줄 수 있습니다.

위 index에서 pk는 GameTitle, sk는 TopScore입니다. base table은 항상 project되기 때문에 pk인 userid가 포함됩니다.

 

GameTitleIndex를 사용하면 meteor blasters의 store들만 보고싶다! 요구 사항을 만족시킬 수 있습니다.

그리고 sk인 topScore로 정렬도 가능합니다. ScanIndexForward = false  패러미터를 함께 주면 역순으로 정렬이 가능하기 떄문에 

score가 가장 높은 user도 찾을 수 있습니다.

 

GSI에서는 key와 더불어 함께 보고싶은 다른 attribute 들을 따로 설정할 수 도 있습니다.

따로 설정하지 않으면 base table의 non-key attribute는 접근 불가합니다.

 

6.2 gsi에서는 key가 유일하지않다.

 

dynamodb에서 table의 key value는 유일해야합니다. 하지만 GSI의 key는 유일할 필요는 없습니다.

위의 예시는 pk: "Comet Quest", sk: 0으로 gsi를 쿼리한 결과인데요, 이처럼 같은 pk, sk의 쌍이 여러개 존재할 수 있습니다.

이 결과값에서는 sk의 value가 모두 갑기 떄문에 순서는 따로 없습니다.

 

6.3  key value가 존재하지않으면 gsi로 item을 찾을 수 없다.

 

예를 들어

 

userid: 400 GameTitle: "Comet Quest"

 

이런 데이터를 테이블에 추가했다고 합시다. 이 데이터에는 GameTitleIndex의 sk인 TopScore에 대한 value가 없기 때문에 GameTitleIndex에 포함되지않습니다.

 

 

 

출처: Amazon dynamodb developer guide

댓글