소개
주문 지원 도구는 선택한 달에 해당하는 올바른 고객의 주문을 보여 줘야 합니다. 항목 하나만 조회하거나 필터링 후 빈 페이지에서 멈추면 유효한 레코드를 놓칠 수 있습니다. 복합 키 테이블을 구축하고 Ada의 10월 주문을 쿼리한 다음, 제공된 애플리케이션이 포장된 주문을 표시할 때 연속 조회 키를 따라가도록 설정합니다.
타입이 지정된 항목과 수정을 포함한 주문용 DynamoDB 테이블 생성 실습을 먼저 완료하세요. 이 단원은 새로운 일회성 연결, 가상 데이터 파일, 일반적인 애플리케이션을 갖춘 독립 환경에서 시작합니다. /home/labex/project, 공식 AWS CLI, AWS View를 사용하세요. 이전 VM 리소스는 재사용하지 않습니다.
인증 시험 관련 주제
이 실습은 다음 시험 주제에 대한 실습 경험을 제공합니다.
- Solutions Architect – Associate (SAA-C03) · 태스크 3.3: DynamoDB 접근 패턴, 키 쿼리와 페이지 나누기.
- Developer – Associate (DVA-C02) · 태스크 1.3: DynamoDB 접근 패턴, 키 쿼리와 페이지 나누기.
- Data Engineer – Associate (DEA-C01) · 태스크 2.1: 기초 실습: DynamoDB 접근 패턴, 키 쿼리와 페이지 나누기.
접근 패턴에 맞춰 키 구성
이 단계에서는 고객 및 날짜 조회가 필요한 주문을 준비합니다. 복합 기본 키는 파티션 키와 정렬 키로 구성됩니다. 파티션 키는 한 고객의 주문을 묶습니다. 정렬 키는 해당 그룹 안에서 각 주문을 식별하고 쿼리 결과의 순서를 정합니다. 두 값을 함께 사용해 항목 하나를 식별합니다.
날짜는 고정 길이 YYYY-MM-DD 문자열 뒤에 #와 주문 ID를 붙여 사용합니다. 문자열 정렬 키는 UTF-8 바이트를 비교하므로 이 형식은 날짜를 시간순으로 유지합니다. 이는 작은 주문 모델이며 모든 상황에 적용되는 단일 테이블 설계는 아닙니다.
cd /home/labex/project
aws sts get-caller-identity
aws dynamodb create-table --table-name labex-d02-orders --attribute-definitions AttributeName=customer_id,AttributeType=S AttributeName=order_key,AttributeType=S --key-schema AttributeName=customer_id,KeyType=HASH AttributeName=order_key,KeyType=RANGE --billing-mode PAY_PER_REQUEST
aws dynamodb wait table-exists --table-name labex-d02-orders
준비된 orders.json에는 자격 증명이 아니라 다섯 개의 가상 주문이 들어 있습니다. cat은 일반적인 API 요청을 출력하므로 데이터를 로드하기 전에 각 고객, 날짜, 상태를 검사할 수 있습니다.
cat orders.json
aws dynamodb batch-write-item --cli-input-json file://orders.json
BatchWriteItem은 이 서로 다른 키들을 로드합니다. UnprocessedItems가 {}인지 확인하세요. AWS에서 처리되지 않은 배치는 재시도가 필요합니다. 응답만으로 모든 쓰기가 완료되었다고 보장할 수 없습니다. 예제에는 Ada의 9월, 10월, 11월 주문과 Bob의 10월 주문이 포함되어 있어, 정상 경로 하나뿐 아니라 경계도 테스트할 수 있습니다.
한 고객과 날짜 범위 쿼리
이 단계에서는 키 조건으로 Ada의 10월 주문을 선택합니다. Query는 파티션 키 하나에 대한 동등 조건이 필요하며 정렬 키 범위를 좁힐 수 있습니다. Scan은 먼저 키 파티션을 선택하는 대신 테이블을 검사합니다. 다음 단계에서는 필터를 추가합니다. 먼저 키를 사용해 고객과 날짜 범위를 선택하세요.

고객 키는 Ada의 파티션을 선택하고 날짜 범위는 그 파티션의 10월 주문을 선택합니다.
먼저 다섯 레코드를 모두 검사해 스캔의 범위를 이해하세요.
aws dynamodb scan --table-name labex-d02-orders --consistent-read --query 'Items'
제공된 주문 조회 애플리케이션은 lookup.json을 읽고 DynamoDB Query API를 호출합니다. 실행 파일은 order-lookup이며, 검사용 소스도 제공됩니다. Python을 작성할 필요는 없습니다. 일반적인 Query 요청 필드를 설정하고 명령 기록 대신 실제 애플리케이션 결과를 검사합니다.
BETWEEN은 양쪽 끝값을 포함합니다. 주문 키는 날짜 뒤에 #와 ID가 붙습니다. 시작값 2026-10-01#는 그날의 ID보다 앞에 옵니다. 끝값 2026-10-31#~는 여기서 사용한 문자와 숫자보다 ~가 뒤에 정렬되므로 그날의 ID보다 뒤에 옵니다. 이 경계는 이 키 형식에만 해당합니다.
따옴표로 감싼 heredoc은 JSON을 그대로 lookup.json에 기록합니다. request에는 Query 필드가 들어 있습니다. paginate: false는 지금은 애플리케이션 페이지 하나만 요청합니다. 다음 단계에서 연속 조회를 활성화합니다.
cat > lookup.json <<'JSON'
{
"paginate": false,
"request": {
"TableName": "labex-d02-orders",
"KeyConditionExpression": "customer_id = :customer AND order_key BETWEEN :start AND :end",
"ExpressionAttributeValues": {
":customer": {
"S": "ada"
},
":start": {
"S": "2026-10-01#"
},
":end": {
"S": "2026-10-31#~"
}
},
"ConsistentRead": true
}
}
JSON
Query 값은 GetItem과 마찬가지로 타입이 지정된 문자열을 사용합니다. 애플리케이션 파일에는 자체 paginate 설정도 있으므로, 같은 키에 대한 직접 CLI 요청과 비교하세요.
aws dynamodb query --table-name labex-d02-orders --key-condition-expression 'customer_id = :customer AND order_key BETWEEN :start AND :end' --expression-attribute-values '{":customer":{"S":"ada"},":start":{"S":"2026-10-01#"},":end":{"S":"2026-10-31#~"}}' --consistent-read
./order-lookup
두 결과에는 정렬 키 오름차순으로 Ada의 O100과 O101만 포함됩니다. Bob의 O200과 Ada의 해당 월 밖 주문은 제외됩니다. AWS View를 열어 저장된 테이블 항목 옆의 실제 Order lookup 결과를 확인하세요. 이러한 읽기는 레코드를 변경하지 않습니다.
아래 공식 Console 예제는 파티션 키 Query를 보여 줍니다. 여기서 Artist와 songTitle은 이 실습의 customer_id 및 order_key와 같은 키 역할을 합니다. 인터페이스를 알아보는 데 참고하고, 실습은 Terminal과 AWS View에서 계속하세요.

출처: AWS DynamoDB 튜토리얼.
필터링 후 페이지가 비어 있어도 페이지네이션 계속
이 단계에서는 첫 페이지가 비어 있어도 멈추지 않고 포장된 10월 주문을 조회합니다. DynamoDB는 필터를 적용하기 전에 평가할 항목에 Limit을 적용합니다. Query 응답은 Items가 비어 있어도 LastEvaluatedKey를 포함할 수 있습니다. 항목 수가 아니라 이 연속 조회 키가 애플리케이션에 다음 페이지를 요청해야 하는지 알려 줍니다. 필터는 이미 수행한 읽기 작업량을 줄이지 않습니다.
준비된 packed-page.json은 같은 키를 유지하고 PACKED 상태 필터를 추가하며 Limit: 1을 설정합니다. 이 작은 제한은 페이지 경계를 눈에 보이게 합니다. --no-paginate는 CLI가 추가 페이지를 가져오지 않게 하므로 서비스 응답 하나를 검사할 수 있습니다.
cat packed-page.json
aws dynamodb query --cli-input-json file://packed-page.json --no-paginate
처음 평가된 주문은 NEW이므로 Items: [], Count: 0, ScannedCount: 1과 O100에 대한 LastEvaluatedKey를 확인하세요. 이것은 결과 집합의 끝이 아닙니다.

처음 두 페이지: 필터로 인해 1페이지는 비어 있지만 연속 조회 키를 따라가면 포장된 주문에 도달합니다.
API가 해당 키를 더 이상 반환하지 않을 때까지 따라가도록 애플리케이션 설정을 작성하세요. #state는 예약어 status를 피하고 :state는 필터 값을 담습니다.
cat > lookup.json <<'JSON'
{
"paginate": true,
"request": {
"TableName": "labex-d02-orders",
"KeyConditionExpression": "customer_id = :customer AND order_key BETWEEN :start AND :end",
"ExpressionAttributeValues": {
":customer": {
"S": "ada"
},
":start": {
"S": "2026-10-01#"
},
":end": {
"S": "2026-10-31#~"
},
":state": {
"S": "PACKED"
}
},
"ConsistentRead": true,
"ExpressionAttributeNames": {
"#state": "status"
},
"FilterExpression": "#state = :state",
"Limit": 1
}
}
JSON
./order-lookup
애플리케이션은 PACKED 상태인 Ada의 O101만 반환하며 Count: 1, Evaluated: 2를 표시합니다. 이 데이터셋에서 Pages: 3에는 쿼리의 끝을 확인하는 마지막 빈 요청이 포함됩니다. 연속 조회 키는 읽기 경계를 나타내며, 조건에 맞는 항목이 더 있다는 것을 보장하지는 않습니다. 애플리케이션은 서비스가 더 이상 반환하지 않을 때까지 ExclusiveStartKey를 따라갑니다. AWS View에서는 조회 결과가 바뀌지만 저장된 모든 레코드는 변경되지 않습니다.

목록 확인 및 소유한 테이블 제거
이 단계에서는 조회 동작을 입증한 뒤 정리합니다. 먼저 대상 테이블에 원래 다섯 레코드가 여전히 있는지 확인하세요. 읽기와 설정 변경은 주문 데이터를 수정하지 않아야 합니다.
aws dynamodb scan --table-name labex-d02-orders --consistent-read --select COUNT
Count: 5를 확인하세요. labex-d02-orders만 삭제하고 부재를 기다리세요. 참조 테이블은 환경에 속하므로 남겨야 합니다.
aws dynamodb delete-table --table-name labex-d02-orders
aws dynamodb wait table-not-exists --table-name labex-d02-orders
aws dynamodb list-tables
aws dynamodb get-item --table-name labex-d02-reference --key '{"id":{"S":"platform"}}' --consistent-read
목록에는 labex-d02-reference만 남고 그 note는 keep unchanged로 유지됩니다. AWS View에서 소유한 테이블과 조회 결과가 제거됩니다. 성공한 서비스 응답은 삭제를 입증하지만 연결을 사용할 수 없는 상태는 그렇지 않습니다. 일회성 연결은 이 VM과 함께 종료됩니다.
요약
고객별로 주문을 묶고 날짜 기반 정렬 키로 순서를 정했습니다. Query는 의도한 파티션과 범위를 선택했고 Scan은 더 넓은 테이블을 검사했습니다. 필터는 평가 후에 적용되며 빈 페이지에서도 연속 조회가 필요할 수 있음을 확인했습니다. 제공된 애플리케이션은 실제 Query 요청으로 여러 페이지에서 포장된 주문을 수집했고, 이후 소유한 리소스만 제거했습니다.



