반응형
AWS DynamoDB 시작하기 - 아마존 다이나모 디비 예제.aws-series-02-dynamodb

목차

  • 1.DynamoDB 설명
  • 2.DynamoDB 스키마
  • 3.DynamoDB - CRUD, Query, Scan

 


2019.03.11 업데이트

로컬 보조 인덱스(Local Secondary index), 글로벌 보조 인덱스(Global Secondary Index) 부분 추가하였습니다.

 


저번 시간에는 AWS Lambda와 API Gateway를 쓰는 법을 알아보았는데요.

이번 시간에는 DynamoDB 쓰는 법을 알아보도록 하겠습니다.

모든 튜토리얼이 끝나면 아래 그림과 같은 구조가 될 거에요!

 

alt text

 

이 예제의 코드는 자바스크립트로 작성되었습니다.

 

DynamoDB란?

DynamoDB(다이나모디비)는 키-밸류 데이터베이스입니다.

NoSQL방식이라서 확장이 간편하고 사용한만큼만 요금을 내는 구조입니다.

DynamoDB는 스키마를 복잡하게 잡지 않아도 되는 게 장점입니다.

스키마와 상관없이 데이터를 추가가하는 게 가능하기 때문이에요.

DynamoDB는 또한 빠르고 안정성 있게 확장이 가능합니다.

다만 정렬용으로는 좀 맞지 않습니다.

정렬을 다채롭게 하는 것도 가능하긴 한데, SQL 데이터베이스에 비하면 좀 까다롭습니다.

 

1. DynamoDB - 테이블 만들기

1.1 - Table

테이블은 데이터를 담는 그릇입니다.

DynamoDB는 관계형 데이터베이스가 아니기에 조인이 없습니다.

대신 파티션 키 (Partition Key)와 정렬 키 (Sort Key)만 있으면 됩니다.

  • 파티션 키 (Parition Key) : 무조건 있어야함. 테이블에 있는 아이템을 어디다가 나눌지 정할 때 쓰임. Hash Key라고도 불림. 파티션 키는 1개만 있어야 됨.
  • 정렬 키 (Sort Key) : 정렬할 때 쓰임. 꼭 있어야되는 건 아님. Range Key라고도 불림.

파티션 키와 정렬 키는 한번 정해지면은 바꿀 수 없습니다.

영화 데이터를 담은 테이블을 만들어볼께요

 

1.1 - Table. 파티션 키만 사용

movie name (Partition Key)duration (minute)date
집으로 가는 날902018.09.10
놀러 가기 좋은 날1202017.02.05
여행 가고 싶은 날1502016.01.03

영화 이름을 파티션 키로 잡아 보았습니다.

파티션 키만 쓸 경우 간단히 테이블을 만들 수 있는 게 장점이지만, 중복된 키가 있을 때 문제가 됩니다.

( 아마존은 e-mail_id, employee_no, customer_id + product_id 처럼 중복되는 값이 없는 걸 권장합니다. )

영화 이름이 같을 경우 문제가 되겠죠?

데이터를 추가하거나, 업데이트할 때 어떤 걸 할지 모르게 되니까요.

 

1.1 - Table. 파티션 키와 정렬 키 사용

위의 테이블에 정렬 키를 더해 볼게요. 영화에 따라 고유하게 부여된 ID 입니다.

이젠 영화 이름이 같아도 데이터를 추가하는 데 없어집니다.

movie name (Partition Key)movie id (Range Key)duration (minute)date
집으로 가는 날a8273uerie902018.09.10
놀러 가기 좋은 날e9a928grjf1202017.03.05
여행 가고 싶은 날d23a8beqo1502016.01.03
여행 가고 싶은 날abc2913eu1252014.06.15

 

이제부터 실습을 해보도록 할께요.

 

**1.1.2 - 실제 사용할 테이블

이 테이블은 음식 정보를 담은 테이블입니다.

음식을 구분하는 id, 종류, 이름, 가격 등이 나와 있죠.

typenamepricesize
양식 (Western Food)까르보나라13000
한식 (Korean Food)족발33000
중식 (Chinese Food)짜장면55000

테이블을 만들 때는 파티션 키 (Paritition Key, 필수)를 정해줘야합니다. 정렬 키(Sort Key)도 있으면 좋으니 만들도록 할께요.

  • 파티션키 (Partition Key) - type

    • 파티션키는 필수입니다!
  • 정렬 키 (Sort key) - name

    • 필수는 아닙니다.
    • 정렬할 때 써요.
    • 다른 키로 정렬하고 싶으면 두번째 정렬 키 (Local Secondary Index나, Global Secondary Index )를 정해주면 됩니다.

 

 

 

1.2 item(항목)

아이템은 테이블에 있는 각각의 행을 말합니다.

위의 음식 테이블에서는 (1,양식,까르보나라,13000,소)가 아이템이 되겠지요.

아이템에 있는 항목은 키(partition key, sort key)만 뺴고 수정할 수 있습니다.

partition key와 sort key를 수정하려면 지우고 새로 만드는 수 밖에 없습니다.

 

1.3 데이터 타입

DynamoDB의 데이터는 크게 3가지 타입이 있습니다.

  • Scalar Type: Number(숫자, N으로 표시), String(문자, S로 표시), Binary(B로 표시), Boolean and Null
  • Document Types: 리스트와 맵
  • Set Types: 숫자 집합(Number Set), 문자 집합(String Set), Binary Set(이진자료형 집합)

 

 

2. DynamoDB 테이블 만들기

2.1. module 설치

이번 예제는 nodejs를 써서 진행하도록 하겠습니다.

일단 aws-sdk를 설치해주세요.

2.2. aws 설정하기

aws-sdk가 설치되었으면 새로 자바크스립트 파일(dynamodb_start.js)을 하나 만들어줍니다.

한국 리전을 설정해주고, 엔드포인트도 변경해줍니다.

2.3. 테이블 만들기

이제 데이터베이스 테이블을 만들어볼께요.

일단 테이블을 어떻게 만들지 정합니다.

파티션 키나, 데이터 읽기 쓰기량을 정하는거죠.

지금 만들 테이블은 요리법이 담겨 있는 테이블입니다.

요리종류(type), 이름(name), 재료(ingredients) 등등이 들어있죠.

정해진 설정을 바탕으로 테이블을 만듭니다.

제대로 만들어졌나요?

성공하면 아래와 같은 메시지가 나옵니다.

 

이제 테이블에서 데이터(아이템)을 읽고, 쓰고, 업데이트 하는 걸 해보도록 할께요.

 

3. DynamoDB - 데이터 활용하기 (CRUD, QUERY)

3.1 CRUD 작업하기

3.1.1 ADD ITEM

일단 아이템을 테이블에 넣어보도록 할께요.

아이템을 넣는 건 테이블을 만드는 거에 비하면 간단합니다.

아이템의 형태는 자유롭게 정할 수 있습니다만, partition key랑 sort key는 빼먹으면 안됩니다!

잘 되었나요?

3개 정도 아이템을 더 더해보도록 하겠습니다.

이번에는 파일에서 읽을께요.

recipes.json - ingredients이 조금씩 달라요.

 

Item의 ingredients가 다르더라도 큰 문제없이 추가가 됩니다.

이런 유연함이 다이나모 디비의 장점이죠.

 

3.1.2 get item

추가한 아이템을 불러와 볼께요.

여러 아이템을 한꺼번에 불러오려면 다른 방법(query, scan)을 써야되지만

아이템 1개만 가져올땐 get을 쓰면 됩니다.

get을 쓸땐 꼭 Key를 적어줘야합니다.

잘 되면은 아래처럼 나올거에요.

 

3.1.3 update item

이번엔 아이템의 값을 수정할께요.

 

방금 수정한 아이템을 불러와 보겠습니다.

 

 

price 가 바뀌었죠?

이처럼 일반 값은 얼마든지 수정할 수 있습니다.

하지만 키(key), 테이블명(table name)은 수정이 안됩니다.

키는 한번 정하면 끝이니 주의하세요.

 

3.1.4 delete item

아이템을 지워보겠습니다.

단순히 지우는 게 아니라 조건을 넣어보겠습니다.

모든 아이템을 다 지우면 곤란하니까요.

sql에서 where를 쓰는 거랑 비슷합니다.

조건은 ConditionExpression 을 써서 정합니다.

 

잘 지워졌나요?

 

지워진 아이템을 가져오려고 하면(get) 아무것도 안 나옵니다.

 

 

지금까지 기본적인 CRUD (Create, Read, Update, Delete)를 알아보았습니다.

이제 데이터를 조회하는 법에서 알아보도록 할께요.

 

3.2 데이터 조회하기

데이터를 조회하는 방법은 2가지 입니다. 쿼리랑 스캔인데요. 쿼리는 파티션 키를 바탕으로 데이터를 찾습니다. 스캔은 전체 테이블에서 데이터를 찾을 때 쓰구요. 일단 쿼리부터 설명해보겠습니다.

3.2.1 query

쿼리를 잘 쓰려면 파티션 키를 잘 정해야합니다. 파티션 키를 통해 데이터를 분산하고, 조회할 때 쓰기 때문이죠.

위에서 파티션 키를 음식 종류(type)로 정했죠. 음식 종류에 따라 음식을 찾기 위해서 입니다. 한식이 500종류, 일식이 200종류, 양식이 1000종류 있는 경우를 생각해 봅시다. 유저가 50대 한국인이여서 한식만 찾는다면 어떤 쿼리를 써야할까요?

한식을 키로 두고 쿼리를 쓰면 되겠죠?

 

쿼리 결과는 아래와 같이 나옵니다. 어렵진 않죠.

다만 다이나모디비의 쿼리는 SQL의 SELECT처럼 자유롭게는 못 쓰고, 파티션 키의 영향을 크게 받는다는 걸 명심하세요.

 

3.2.2 query - 다른 키로 정렬하기, 보조 인덱스

다이나모 디비는 정렬키로 데이터로 정렬합니다. 하지만 정렬키 만으로는 부족할 때가 있죠.

 

그때는 새 인덱스를 추가해 정렬 할 때 씁니다.

새 인덱스를 더하는 방법은 2가지입니다.

 

하나는 로컬 보조 인덱스 (Local Secondary Index, 두번째 지역 인덱스)이고

다른 하나는 글로벌 보조 인덱스 (Global Secondary Index, 글로벌 두번째 키) 입니다.

 

  • 로컬 보조 인덱스

    • 테이블을 만들 때 정해야됨
    • 테이블을 만들고 추가 못함
    • 인덱스를 써서 정렬해도, 읽기 쓰기 사용량이 늘어나지 않음
    • 강력한 일관성과 최종 일관성(Eventual consistency)을 보장함.
    • 인덱스 크기 제한이 있음 (10 GB 이하)

 

  • 글로벌 보조 인텍스

    • 테이블 만들고도 추가할 수 있음

    • 테이블을 복제해서 새 인덱스를 추가함.

    • 추가할 때마다, 읽기 쓰기 사용량이 늘어남

    • 최종 일관성만 보장함.

    • 인덱스 크기 제한이 없음 (No partition key size limits)

       

일단 로컬 보조 인덱스부터 알아볼께요.

 

3.2.3. query - Local Secondray Index

로컬 보조 인덱스는 테이블을 만들때만 정할 수 있습니다.

전에 만든 테이블을 지우고, 새로 테이블을 만들어 볼께요.

테이블 삭제

 

음식의 가격별로 쿼리할 수 있게, price를 새로운 인덱스로 정하겠습니다.

 

인덱스 있는 새 테이블 만들기

 

테이블이 만들어졌나요?

이제 인덱스를 써서 쿼리를 할 수 있습니다.

테이블을 새로 만들었으니, 데이터를 넣어주세요 (위의 데이터 넣는 코드를 참고해주세요)

그럼 조회를 해보겠습니다. 가격 순으로 조회를 할거에요.

인덱스로 조회

 

제대로 되었으면 음식이 가격순으로 나올 거에요.

 

3.2.3 query - Global Secondary Index

글로벌 보조 인덱스는 전에 만든 테이블을 써서 만듭니다.

인덱스로 쓰일 속성은 orderCount입니다.

주문량이 많은 음식순으로 정렬을 하려고 합니다~!

글로벌 보조 인덱스를 만들었으니, 이 인덱스로 조회해 볼께요.

 

 

조회 결과

 

orderCount(주문량) 순으로 조회가 되네요!

 

이렇게 다이나모 디비도 정렬을 원하는 대로 할 수 있지만,

테이블 만들 때 인덱스를 정하거나, 나중에 추가해줘야하는 번거로움이 있습니다.

 

3.3 scan

스캔은 전체 테이블에서 데이터를 찾을 때 사용합니다.

스캔은 데이터 양이 많을수록 처리량이 많아서 비효율적이 되죠.

그렇지만 필터를 쓰면 SQL을 쓰는 것처럼 편하게 데이터 조회가 가능한 게 장점입니다.

키를 지정하지 않아도 되는게 쿼리(query)와의 차이점이죠.

실행을 하면 전체 데이터를 조회해서 출력합니다.

지금은 데이터가 몇개 안되지만 테이블이 클수록 양이 엄청나겠죠?

전체 데이터를 스캔하지 말고 필터해서 필요한 데이터만 쓰도록 할께요.

실행하면 아래처럼 나옵니다.

 

필터링을 하면 필요한 값만 쓸 수 있습니다.

다만 필터링을 해도 테이블을 다 확인하는 건 동일하다고 하네요.

데이터베이스 입장에서는 필터를 하나, 안 하나 큰 차이가 없는 거지요.

스캔을 적게 써야하는 건 이때문입니다.

 

기타 주의할점 - 테이블명 짓기

테이블이나 인덱스명을 정할 때는 규칙이 있습니다. 3~255자 사이의 글자여야하고, 다음의 문자만 포함할 수 있어요.

  • a-z
  • A-Z
  • 0-9
  • _ (underscore)
  • - (dash)
  • . (dot)

 

자세한 건 아마존 공식 문서 를 참고해주세요.

 

기타 주의할점 - 다이나모 DB를 쓸 때 고려할점

을 읽고 정리해 보았습니다. 공감이 가더군요.

  • SQL처럼 쿨하게 조회가 안된다. Key-Value 데이터베이스에 익숙하면 괜찮지만 RDMS에서 바로 왔으면 난감할 수도
  • 개발 및 유지 보수가 간단하지 않다. 학습 곡선이 좀 있더군요.
  • 해시키 잘 정해야한다. 중간에 못 바꾼다.

장점은 꾸준히 빠르다. 확장이 편리하다 입니다.

 

기타 주의할점 - 스캔 효율적으로 쓰기

아마존의 베스트 프랙티스를 요약해보았습니다.

Best Practice for Querying and Scanning

  • Reduce page size - 스캔을 할 때는 페이지 크기를 줄이기를 권하고 있습니다. 기본값은 1mb인데 Limit 변수를 쓰면 한번에 읽는 페이지수를 조절할 수 있죠.
  • Isolate scan operations - 복제 테이블(shadow table)을 만들기를 권합니다. 특정 용도를 위해 테이블을 만들면 스캔때문에 생기는 병목 현상을 막을 수 있습니다. read capacity를 과도하게 쓰는 것도 피할 수 있죠.

마무리

오늘은 다이나모 DB에 대해서 알아보았는데요.

다음에는 서버리스 프레임워크 (Serverless Framework)의 사용법과 람다, 다이나모 DB의 연결을 해보도록 하겠습니다.

 

 

반응형

+ Recent posts