아이템 삭제시 단일 삭제만 가능하여 하루치 데이터를 저장하고 해당 테이블을 S3로 저장한 뒤에 테이블 삭제하는 방법으로 해결
DynamoDB에서 Scan, query를 수행할 때 수행 결과가 최대 1MB를 넘지 못한다. 1MB가 넘는 데이터를 전체 조회하기 위해서는 조회 결과에 포함되어 있는 항목인 LastEvaluatedKey의 존재 유무를 판단하여 추가 검색이 필요한지 판단하여 처리
@Test
void dynamoDB_queryTest() {
int want = 0;
Map<String, AttributeValue> lastKeyEvaluated = null;
do {
ScanRequest scanRequest = new ScanRequest()
.withTableName("Test")
.withExclusiveStartKey(lastKeyEvaluated);
ScanResult result = amazonDynamoDb.scan(scanRequest);
want = want + result.getCount();
lastKeyEvaluated = result.getLastEvaluatedKey();
System.out.println(result.getItems());
Map<String, AttributeValue> key = new HashMap<>();
for (Map<String, AttributeValue> map : result.getItems()) {
key.put("id", map.get("id"));
DeleteItemRequest deleteItemRequest = (new DeleteItemRequest())
.withTableName("BeaconHistoryData")
.withKey(key);
amazonDynamoDb.deleteItem(deleteItemRequest);
}
} while (lastKeyEvaluated != null);
System.out.println(want);
}
DynamoDB table 조회시 table의 파티션 키가 아닌 글로벌 인덱스로 조회하고자 할 때 Java SDK 기준
검색하고자 하는 table을 설정하고 해당 Table 클래스에 포함되어 있는 getIndex에 파라미터로 검색하고자 하는 글러벌 인덱스 값을 넣어서 Index 인스턴스 생성
생성된 Index 인스턴스에 QuerySpec을 생성하여 query 매소드를 통해서 원하는 값을 검색합니다. 쿼리 생성 요소
@Test
void check_performance(){
long start = System.currentTimeMillis();
DynamoDB dynamoDB = new DynamoDB(amazonDynamoDb);
Table table = dynamoDB.getTable("Test");
int [] assetId_list = new int[] {1,2,3,4,5,6,7,8,9,10};
Index index = table.getIndex("byAssetId");
for(Integer nowAsset : assetId_list) {
QuerySpec querySpec = new QuerySpec().withKeyConditionExpression("assetId = :v_id and createdAt between :v_start_at and :v_end_at")
.withValueMap(new ValueMap().withInt(":v_id", nowAsset).withString(":v_start_at", "원하는 값").withString(":v_end_at", "원하는 값"));
ItemCollection<QueryOutcome> items = index.query(querySpec);
Iterator<Item> iterator = items.iterator();
Item item = null;
Integer count = 0;
List<TestDTO> test_perform = new ArrayList<>();
Long base_placeId = 0L;
Long base_timestamp = 0L;
Long current_timestamp = 0L;
Long durationTime = 0L;
while (iterator.hasNext()) {
item = iterator.next();
count += 1;
TestDTO test = TestDTO.builder()
// 원하는 값
.build();
// 원한는 동작
}
}
System.out.println("총 개수는" + count);
System.out.println("리스트의 길이는 " + test_perform.size());
Iterator<TestDTO> test_list = test_perform.iterator();
while (test_list.hasNext()) {
TestDTO temp = test_list.next();
System.out.println("머문시간은 " + temp.getStayTime().toString());
}
}
long end = System.currentTimeMillis();
System.out.println("수행시간: " + (end - start) + " ms");
}
문제 발생 시 Cloudwatch의 로그 그룹을 통해서 에러 log 확인 가능cloudWatch log group 바로가기
Java SDK 기준 테이블을 생성할 때 모든 항목을 만들 필요가 없다. 테이블의 (파티션 키, 정렬 키), 글로벌 인덱스에 선언된 (파티션 키, 정렬 키), 로컬 인덱스에서 선언된 (파티션 키, 정렬 키) 만 생성해주면 된다.
table = dynamodb.create_table(
AttributeDefinitions = [
{'AttributeName': 'A', 'AttributeType': 'N'}
, {'AttributeName': 'B', 'AttributeType': 'S'}
, {'AttributeName': 'C', 'AttributeType': 'S'}
, {'AttributeName': 'E', 'AttributeType': 'S'}
, {'AttributeName': 'D', 'AttributeType': 'N'}],
TableName = "KongPlace_"+str(index)+"_"+str(next_day)[:10],
KeySchema = [{'AttributeName': 'E', 'KeyType': 'HASH'}],
GlobalSecondaryIndexes = [
{'IndexName': 'byA', 'KeySchema': [{'AttributeName': 'A', 'KeyType': 'HASH'}, {'AttributeName': 'C', 'KeyType': 'RANGE'}], 'Projection': {'ProjectionType': 'ALL'}}
, {'IndexName': 'byB', 'KeySchema': [{'AttributeName': 'B', 'KeyType': 'HASH'}], 'Projection': {'ProjectionType': 'ALL'}}
, {'IndexName': 'byD', 'KeySchema': [{'AttributeName': 'D', 'KeyType': 'HASH'}], 'Projection': {'ProjectionType': 'ALL'}}],
BillingMode = 'PAY_PER_REQUEST')
https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/Scan.html
https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/GSIJavaDocumentAPI.html
https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/APIReference/API_CreateTable.html