티스토리 뷰

do/DynamoDB

DynamoDB #2

dooo.park 2020. 8. 11. 18:08

Amazon DynamoDB CRUD API

1. 데이터 생성

  • PutItem – 테이블에 단일 항목을 쓴다. 기본 키 속성은 꼭 지정해야 하지만 다른 속성은 지정하지 않아도 된다.

  • BatchWriteItem – 테이블에 최대 25개의 항목을 쓴다. 여러 항목을 삭제하는 경우에 BatchWriteItem을 사용할 수도 있다.

2. 데이터 읽기

  • GetItem – 테이블에서 단일 항목을 가져온다. 항목의 기본 키를 지정해야 하고. 전체 항목 또는 속성 일부만 가져올 수 있다.

  • BatchGetItem – 하나 이상의 테이블에서 최대 100개의 항목을 가져온다. 

  • Query – 특정 파티션 키가 있는 모든 항목을 가져온다. 파티션 키 값을 지정해야 한다.
    전체 항목 또는 속성 일부만 가져올 수 있다.
    경우에 따라 정렬 키 값에 조건을 적용하여 파티션 키가 동일한 데이터의 하위 집합만 검색할 수도 있다.

  • Scan – 지정한 테이블 또는 인덱스의 모든 항목을 가져온다.
    전체 항목 또는 속성 일부만 가져올 수 있다. 필터링 조건을 적용하여 필요한 값만 반환하고 나머지는 버릴 수 있다.

3. 데이터 업데이트

  • UpdateItem – 항목에서 하나 이상의 속성을 수정한다. 수정하려는 항목의 기본 키를 지정해야 한다.
    새로운 속성을 추가할 수 있으며 기존 속성을 수정하거나 제거할 수 있다.
    조건부 업데이트를 수행하여 조건을 만족할 때만 업데이트가 수행되도록 할 수도 있다. 

4. 데이터 삭제

  • DeleteItem – 테이블에서 단일 항목을 삭제합니다. 삭제하려는 항목의 기본 키를 지정해야 합니다.

  • BatchWriteItem – 하나 이상의 테이블에서 최대 25개의 항목을 삭제한다.
    BatchWriteItem을 사용하여 하나 이상의 테이블에 여러 아이템을 추가할 수도 있다.


DynamoDB Java SDK 예제

1. 테이블 생성

다음과 같은 기본키를 가지는 Movies라는 테이블을 생성한다.

- year : 파티션 키

- title : 정렬 키

- createTable 호출에서 테이블 이름, 기본 키 속성 및 데이터 유형을 지정한다.

public class MoviesCreateTable {

    public static void main(String[] args) throws Exception {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
            .build();

        DynamoDB dynamoDB = new DynamoDB(client);

        String tableName = "Movies";

        try {
            Table table = dynamoDB.createTable(tableName, // 테이블 생성
                Arrays.asList(new KeySchemaElement("year", KeyType.HASH), // Partition
                                                                          // key
                    new KeySchemaElement("title", KeyType.RANGE)), // Sort key
                Arrays.asList(new AttributeDefinition("year", ScalarAttributeType.N),
                    new AttributeDefinition("title", ScalarAttributeType.S)),
                new ProvisionedThroughput(10L, 10L));
            table.waitForActive();

        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }

    }
}

 

2. 테이블에 샘플 데이터 저장

- year 및 title을 Movies 테이블을 위한 기본 키 속성 값으로 사용한다.

- info의 나머지 값들은 info라는 단일 속성에 저장한다.

 

- 영화 데이터 JSON

{
    "year" : 2013, // 파티션 키
    "title" : "Turn It Down, Or Else!", // 정렬 키
    "info" : { // 나머지 데이터
        "directors" : [
            "Alice Smith",
            "Bob Jones"
        ],
        "release_date" : "2013-01-18T00:00:00Z",
        "rating" : 6.2,
        "genres" : [
            "Comedy",
            "Drama"
        ],
        "image_url" : "http://ia.media-imdb.com/images/N/O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg",
        "plot" : "A rock band plays their music at high volumes, annoying the neighbors.",
        "rank" : 11,
        "running_time_secs" : 5215,
        "actors" : [
            "David Matthewman",
            "Ann Thomas",
            "Jonathan G. Neff"
       ]
    }
}

 

- 데이터 생성 함수

public class MoviesLoadData {

    public static void main(String[] args) throws Exception {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
            .build();

        DynamoDB dynamoDB = new DynamoDB(client);

        Table table = dynamoDB.getTable("Movies");

        JsonParser parser = new JsonFactory().createParser(new File("moviedata.json"));

        JsonNode rootNode = new ObjectMapper().readTree(parser);
        Iterator<JsonNode> iter = rootNode.iterator();

        ObjectNode currentNode;

        while (iter.hasNext()) {
            currentNode = (ObjectNode) iter.next();

            int year = currentNode.path("year").asInt();
            String title = currentNode.path("title").asText();

            try {
                table.putItem(new Item().withPrimaryKey("year", year, "title", title).withJSON("info",
                    currentNode.path("info").toString())); // 데이터 1개씩 저장
            }
            catch (Exception e) {
                System.err.println(e.getMessage());
                break;
            }
        }
        parser.close();
    }
}

 

3. 데이터 읽기

getItem 메서드를 사용하여 Movies 테이블에서 항목을 읽어올 수 있다.

기본 키 값을 지정해야 Movies과 year을 알고 있을 때 title에서 항목을 읽어올 수 있다.

 

public class MoviesItemOps02 {

    public static void main(String[] args) throws Exception {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
            .build();

        DynamoDB dynamoDB = new DynamoDB(client);

        Table table = dynamoDB.getTable("Movies");

        int year = 2015;
        String title = "The Big New Movie";

        GetItemSpec spec = new GetItemSpec().withPrimaryKey("year", year, "title", title);

        try {
            Item outcome = table.getItem(spec); // 데이터 읽기
        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }

    }
}

 

4. 데이터 업데이트

updateItem 메서드를 사용해 기존 항목을 수정할 수 있다.

기존 속성의 값을 업데이트하거나 새로운 속성을 추가하거나 속성을 제거할 수 있다.

 

다음에서는 다음과 같이 업데이트를 수행한다.

- 기존 속성(rating, plot)의 값 변경

- 기존 info 맵에 새로운 목록 속성(actors) 추가

 

public class MoviesItemOps03 {

    public static void main(String[] args) throws Exception {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
            .build();

        DynamoDB dynamoDB = new DynamoDB(client);

        Table table = dynamoDB.getTable("Movies");

        int year = 2015;
        String title = "The Big New Movie";

        UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("year", year, "title", title)
            .withUpdateExpression("set info.rating = :r, info.plot=:p, info.actors=:a")
            .withValueMap(new ValueMap().withNumber(":r", 5.5).withString(":p", "Everything happens all at once.")
                .withList(":a", Arrays.asList("Larry", "Moe", "Curly")))
            .withReturnValues(ReturnValue.UPDATED_NEW);

        try {
            UpdateItemOutcome outcome = table.updateItem(updateItemSpec); // 데이터 업데이트
        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}

 

5. 데이터 쿼리

다음에서는 다음과 같은 쿼리를 수행한다.

- 1985year에 개봉한 모든 영화를 조회

- 1992year에 개봉한 영화 중에 title이 "A"부터 "L"까지의 알파벳으로 시작하는 영화를 모두 조회

 

- 쿼리 파라미터를 설명하는 querySpec 객체를 생성한 후 그 객체를 query 메서드로 전달한다.

 

public class MoviesQuery {

    public static void main(String[] args) throws Exception {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
            .build();

        DynamoDB dynamoDB = new DynamoDB(client);

        Table table = dynamoDB.getTable("Movies");

        HashMap<String, String> nameMap = new HashMap<String, String>();
        nameMap.put("#yr", "year");

        HashMap<String, Object> valueMap = new HashMap<String, Object>();
        valueMap.put(":yyyy", 1985);

        QuerySpec querySpec = new QuerySpec().withKeyConditionExpression("#yr = :yyyy").withNameMap(nameMap)
            .withValueMap(valueMap); // 쿼리 조건 추가

        ItemCollection<QueryOutcome> items = null;
        Iterator<Item> iterator = null;
        Item item = null;

        try {
            items = table.query(querySpec); // 데이터 쿼리
            iterator = items.iterator();
            while (iterator.hasNext()) {
                item = iterator.next();
            }

        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }

        valueMap.put(":yyyy", 1992);
        valueMap.put(":letter1", "A");
        valueMap.put(":letter2", "L");

        querySpec.withProjectionExpression("#yr, title, info.genres, info.actors[0]")
            .withKeyConditionExpression("#yr = :yyyy and title between :letter1 and :letter2").withNameMap(nameMap)
            .withValueMap(valueMap); // 쿼리 조건 추가

        try {
            items = table.query(querySpec); // 데이터 쿼리
            iterator = items.iterator();
            while (iterator.hasNext()) {
                item = iterator.next();
            }

        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}

 

6. 스캔

scan 메서드는 테이블 전체의 모든 항목을 읽고 테이블의 모든 데이터를 반환한다.

선택 사항인 filter_expression을 제공할 수 있으며 그 결과 기준과 일치하는 항목만 반환된다.

★ 그러나 필터는 테이블 전체를 스캔한 후에만 적용된다.

 

다음에서는 항목이 약 5,000개인 Movies 테이블 전체를 스캔한다.

스캔은 선택 사항인 필터를 지정하여 1950년대 이후의 영화(약 100개 항목)만 가져오고 그 외의 것들은 모두 무시한다.

 

public class MoviesScan {

    public static void main(String[] args) throws Exception {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
            .build();

        DynamoDB dynamoDB = new DynamoDB(client);

        Table table = dynamoDB.getTable("Movies");

        ScanSpec scanSpec = new ScanSpec().withProjectionExpression("#yr, title, info.rating")
            .withFilterExpression("#yr between :start_yr and :end_yr").withNameMap(new NameMap().with("#yr", "year"))
            .withValueMap(new ValueMap().withNumber(":start_yr", 1950).withNumber(":end_yr", 1959));
		// 스캔 조건
        try {
            ItemCollection<ScanOutcome> items = table.scan(scanSpec); // 스캔

            Iterator<Item> iter = items.iterator();
            while (iter.hasNext()) {
                Item item = iter.next();
            }

        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}

 

7. 테이블 삭제

public class MoviesDeleteTable {

    public static void main(String[] args) throws Exception {

        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
            .build();

        DynamoDB dynamoDB = new DynamoDB(client);

        Table table = dynamoDB.getTable("Movies");

        try {
            table.delete(); // 테이블 삭제
            table.waitForDelete();
        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}

참고 : https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/HowItWorks.API.html

'do > DynamoDB' 카테고리의 다른 글

Dynamo DB #1  (0) 2020.08.06
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함