[Database] DynamoDB GSI 사용

DynamoDB 제일 중요한 개념이 GSI(Global Secondary Index)인것 같다. 이 개념은 Partition Key(PK)로 여러 노드에 분산된 데이터를 더 빨리 scan하기 위해 도입된 개념이다. GSI는 파티션 내의 partition key와 sort key와는 분리된 개념이라고 생각하면 된다. 이 기능은 광역에서 데이터를 더 빨리 찾기위한 Index라고 이해하면 될것 같다.

GSI를 이해하기 위한 간단한 예

상품 데이터를 관리하기 위해 상품의 ID을 partition key로 입고일자를 sort key로 하고 입고자 정보를 포함한 schema가 있다고 가정하면 입고자가 입고한 모든 상품을 검색할 때는 입고자를 기준으로 모든 상품을 찾을 시에는 GSI를 입고자로 설정하면 입고자를 기준으로 검색하면 빠르게 데이터를 검색할 수 있다.

Spring-datad 에서의 사용

@DynamoDBTable(tableName = "ProductInfo")
public class ProductInfo {
    private String id;
    private String name;
    private String cost;
    private LocalDateTime createAt;

    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    public String getId() {
        return id;
    }

    @DynamoDBAttribute
        @DynamoDBIndexRangeKey(globalSecondaryIndexName = "NameIndex")
    public String getName() {
        return name;
    }

    @DynamoDBAttribute
    public String getCost() {
        return cost;
    }

    @DynamoDBAttribute
    @DynamoDBIndexRangeKey(globalSecondaryIndexName = "createTimeIndex")
    public LocalDateTime getCreateAt(){
        return createAt;
    }

    public void setCost(String cost) {
        this.cost = cost;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Builder
    public ProductInfo(String name, String cost, LocalDateTime createAt){
        this.name = name;
        this.cost = cost;
        this.createAt = createAt;
    }
}

위와 같이 GSI를 추가하고 아래와 같이 사용할 수 있다.

@Repository
public class ProductInfoRepositoryImpl implements ProductInfoRepository {

    @Autowired
    private DynamoDBMapper dynamoDBMapper;

    @Override
    public List<ProductInfo> findProductInfoByGSI(String name) {
        HashMap<String, AttributeValue> eav = new HashMap<>();
        eav.put(":v1", new AttributeValue().withS(name));

        DynamoDBQueryExpression<ProductInfo> queryExpression = new DynamoDBQueryExpression<ProductInfo>()
                .withIndexName("NameIndex")
                .withConsistentRead(false)
                .withKeyConditionExpression("Name = :v1")
                .withExpressionAttributeValues(eav);

        List<ProductInfo> iList = dynamoDBMapper.query(ProductInfo.class, queryExpression);

        return iList;
    }
}

Ref

https://medium.com/@leohoc/dynamodb-and-spring-data-a81c546a1305

https://zhuanlan.zhihu.com/p/101965292

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/GSI.html

'DataBase' 카테고리의 다른 글

[Python] DynamoDB 및 Mysql 접근법  (0) 2021.12.21
[DynamoDB] Partition Key 설계  (0) 2021.12.21
[DynamoDB] Spring에서 DynamoDB 사용  (0) 2021.12.16
PostgreSQL Transaction isolation level  (0) 2021.12.13
ORM 장단점  (0) 2021.12.12