목차
- DynamoDB와 같은 Wide Columns DB는 RDB에 비해서 더 확장성(scalability)을 가지는가 ?
- 그거 알아요 ? DynamoDB는 HTTP로 통신한다는거 (RDB 운영 이슈, Transaction, Conflict)
- DynamoDB에서 사용하는 용어 정리
- DynamoDB는 사용한 만큼 비용을 냅니다
- http API 실습히가 - Write 편
- http API 실습히가 - Read 편
- 제약사항과 그 철학
- 아키텍처 구조 이해하기
- Schema Modeling 하는 과정
개요
안녕하세요. 저희는 지난 포스팅 [DynamoDB] DynamoDB http API 실습하기 - Write 편에서는 DynamoDB API 중 생성, 수정 그리고 삭제에 대한 Write API를 알아보았습니다. 오늘은 이어서 Read 관점을 Http API를 알아보도록 하겠습니다.
읽기(Read)
기본적으로 DynamoDB의 읽기는 3가지로 구분됩니다.
- 단건 Item 을 읽어오는 Item 기준 읽기
- Partition Key를 기준으로 Item Collection을 읽어오는 Query
- 전체 아이템을 읽어오는 Scan
각 읽기의 용도는 각각의 읽기 API에 대해설명하면서 함께 알아보도록 하겠습니다.
단건 읽기
Primary Key를 기반으로 단건을 읽어옵니다. 또는 Bulk Read를 통해서 다건의 데이터를 읽어오는 방법이 있습니다. 이 경우 DynamoDB는 굉장히 빠른 속도로 읽는 것을 보장해줍니다. 왜냐하면 Item이 어디에 위치해 있는지 정확하게 알 수 있기 때문입니다. Item 단건을 읽는 때는 아래의 정보가 Request에 필요합니다.
- X-Amz-Target : DynamoDB_20120810.GetItem
- Body에 추가 정보
- Table 이름
- Primary Key 정보 ( Partition Key 와 Sort Key )
이전 포스팅에서도 언급했듯이 DynamoDB의 low level API에서는 X-Amz-Target을 통해서 하고자하는 행위를 정의합니다. 예시로 아래의 요청을 통해서 우리는 실제 데이터를 가져올 수 있습니다.
curl --location 'http://localhost:4566/' \
--header 'Content-Type: application/x-amz-json-1.0' \
--header 'Authorization: AWS_SIGNATURE' \
--header 'X-Amz-Target: DynamoDB_20120810.GetItem' \
--data '{
"TableName": "user_order",
"Key": {
"PK": {"S": "USER#123"},
"SK": {"S": "ORDER#2024-01-02"}
}
}'
읽어온 데이터는 아래와 같습니다. 단건 읽기는 실제로 읽은 Item을 Json을 형태로 읽습니다. 읽을 때는 "S": "ORDER#2024-01-02"
처럼 해당 Attribute의 타입까지 함께 반환되게 됩니다.
{
"Item": {
"SK": {
"S": "ORDER#2024-01-02"
},
"PK": {
"S": "USER#123"
},
"title": {
"S": "Coke 2L"
},
"status": {
"S": "DELIVERY"
}
}
}
Query
두번째로 Query에 대해서 알아보도록 하겠습니다. Query는 동일한 Parition Key를 기준으로 Item Collection을 조회하는 방법입니다. Partition Key를 기준으로 조회하기 때문에 조회 성능이 단건 조회와 유사하게 빠른 성능을 보입니다.
- X-Amz-Target : DynamoDB_20120810.Query
- Body에 추가 정보
- Table 이름
- Partition Key 정보를 KeyConditionExpression을 통해서 기술
- ExpressionAttributeValues와 ExpressionAttributeKeys 사용 가능
curl --location 'http://localhost:4566' \
--header 'Content-Type: application/x-amz-json-1.0' \
--header 'Authorization: AWS_SIGNATURE' \
--header 'X-Amz-Target: DynamoDB_20120810.Query' \
--data '{
"TableName": "user_order",
"KeyConditionExpression": "PK = :pk",
"ExpressionAttributeValues": {
":pk": {"S": "USER#123"}
}
}'
{
"Items": [
{
"SK": {
"S": "ORDER#2024-01-01"
},
"PK": {
"S": "USER#123"
},
"title": {
"S": "Coke 1L"
},
"status": {
"S": "DELIVERY"
}
},
{
"SK": {
"S": "ORDER#2024-01-02"
},
"PK": {
"S": "USER#123"
},
"title": {
"S": "Coke 2L"
},
"status": {
"S": "READY"
}
}
],
"Count": 2,
"ScannedCount": 2
}
Return 필드에 본인 데이터 뿐만 아니라 metadata로 Count와 ScannedCount가 있는것을 확인할 수 있습니다. 사실 Read에서는 추가로 Filter와 Projection이 Read에서는 가능합니다. Filter를 이용하면 row를 기반으로 필요없는 row를 선제적으로 제거해서 데이터를 가져올 수 있습니다. 그리고 Projection을 이용하면 특정 필드만 가져오는것도 가능합니다. 관련한 예시는 아래에서 별도로 확인하도록 하겠습니다.
Scan
Scan은 DynamoDB에서 모든 데이터를 읽는데 사용합니다. 주로 Migration 또는 backfill 등을 할 때 사용합니다. DynamoDB는 한번 테이블을 설계하면 Query 변경 및 추가가 원하는대로 안될 수 있기 때문에 스키마 변경등에서 필요합니다. 따라서 Scan이 아주 사용이 안되는건 아닙니다.
Scan은 아래의 파라미터를 요청으로 받습니다. body로는 TableName만 받으면 데이터를 가져올 수 있다는것이 특징입니다.
curl --location 'http://localhost:4566/' \
--header 'Content-Type: application/x-amz-json-1.0' \
--header 'Authorization: AWS_SIGNATURE' \
--header 'X-Amz-Target: DynamoDB_20120810.Scan' \
--data '{
"TableName": "user_order"
}'
{
"Items": [
{
"SK": {
"S": "ORDER#2024-01-01"
},
"PK": {
"S": "USER#124"
},
"title": {
"S": "Coke 1L"
},
"status": {
"S": "DELIVERY"
}
},
{
"SK": {
"S": "ORDER#2024-01-01"
},
"PK": {
"S": "USER#123"
},
"title": {
"S": "Coke 1L"
},
"status": {
"S": "DELIVERY"
}
},
{
"SK": {
"S": "ORDER#2024-01-02"
},
"PK": {
"S": "USER#123"
},
"title": {
"S": "Coke 2L"
},
"status": {
"S": "READY"
}
}
],
"Count": 3,
"ScannedCount": 3
}
읽기에 특화된 Expression
추가로 읽기에 특화된 Expression을 각각 알아보도록 하겠습니다.
Projection Expression
Projection Expression은 DynamoDB에서 특정 컬럼을 가져오는 것을 가능하게 합니다. DynamoDB는 Primary Key를 제외한 Attritube에 대해서 자유도가 높습니다. 따라서 경우에 따라서 Projection은 필수 일 수 있습니다. 특히 한 테이블에 여러 Schema Design을 하는 Single Table Design 설계할 때 주로 사용할 수 있습니다.
Projection 을 사용하면 RCU 적으로 이득일거라고 생각하실 수 있습니다. 하지만 결론적으로 말씀드리면 Projection은 Router에서 일어나는 행위로 RCU 적인 이득은 없습니다. 하지만 데이터 Read 관점에서는 데이터를 덜 전송하므로 이득이 맞습니다.
curl --location 'http://localhost:4566/' \
--header 'Content-Type: application/x-amz-json-1.0' \
--header 'Authorization: AWS_SIGNATURE' \
--header 'X-Amz-Target: DynamoDB_20120810.Query' \
--data '{
"TableName": "user_order",
"KeyConditionExpression": "PK = :pk",
"ExpressionAttributeValues": {
":pk": {"S": "USER#123"}
},
"ProjectionExpression": "PK, SK"
}'
{
"Items": [
{
"SK": {
"S": "ORDER#2024-01-01"
},
"PK": {
"S": "USER#123"
}
},
{
"SK": {
"S": "ORDER#2024-01-02"
},
"PK": {
"S": "USER#123"
}
}
],
"Count": 2,
"ScannedCount": 2
}
Filter Expression
Filter Expression은 반환되는 item 중에서 조건에 부합하는 item만 반환하게 하는 Expression 입니다. 주로 Query 또는 Scan에서 조건에 부합하는 데이터만 가져오는데 사용할 수 있습니다.
이를 사용하면 RCU 적으로 이득이라고 생각하실 수 있지만 이 행위는 Request Router에서 일어나기 때문에 Projection과 마찬가지로 RCU 적인 이득은 없습니다. 하지만 DynamoDB의 리소스를 사용해서 데이터를 필터할 수 있고 Response 받는 데이터의 크기를 적게 가져갈 수 있다는 장점이 있습니다.
아래의 예제는 Scan에서 FilterExpression을 통해서 전체 데이터 중 원하는 데이터만 가져오는 쿼리입니다. Response를 보시면 ScannedCount는 전체 카운트인 2이지만 실제 반환된 카운트는 1인것을 확인할 수 있고 실제 데이터도 1개만 반환된것을 확인할 수 있습니다.
curl --location 'http://localhost:4566/' \
--header 'Content-Type: application/x-amz-json-1.0' \
--header 'Authorization: AWS_SIGNATURE' \
--header 'X-Amz-Target: DynamoDB_20120810.Scan' \
--data '{
"TableName": "user_order",
"FilterExpression": "SK = :SK",
"ExpressionAttributeValues": {
":SK": {"S": "ORDER#2024-01-01"}
}
}'
{
"Items": [
{
"SK": {
"S": "ORDER#2024-01-01"
},
"PK": {
"S": "USER#124"
},
"title": {
"S": "Coke 1L"
},
"status": {
"S": "DELIVERY"
}
}
],
"Count": 1,
"ScannedCount": 2
}
마무리
오늘은 이렇게 Read 관점에서 DynamoDB API를 이해해보았습니다.
감사합니다.
참고
[1] https://sabarada.tistory.com/274
[2] https://docs.localstack.cloud/references/coverage/coverage_dynamodb/
[3] https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html
'datasource > DyanmoDB' 카테고리의 다른 글
[DynamoDB] 아키텍처 구조 이해하기 (flow, RR, Partition) (0) | 2025.03.23 |
---|---|
[DynamoDB] DynamoDB를 사용할 때 알아둬야 할 제한사항과 그 철학 (0) | 2025.03.22 |
[DynamoDB] DynamoDB http API 실습하기 - Write 편 (0) | 2025.03.03 |
[DynamoDB] DynamoDB는 읽고 쓰는 만큼 비용을 냅니다 (0) | 2025.02.17 |
[DynamoDB] DynamoDB에서 사용하는 용어 정리 (0) | 2025.02.13 |
댓글