Database/DynamoDB

DynamoDB - DynamoDB 의 주요 컴포넌트

소농배 2022. 12. 19. 13:53

  DynamoDB 의 테이블(Table), 아이템(Item), 속성(Attribute)은 DynamoDB 를 다루기위한 주요 컴포넌트들이다.  Attribute 들이 모여 하나의 Item 을 이루고 Item 들이 모여 하나의 Table 을 이룬다. Primary Key 를 사용하여 테이블의 아이템들을 구별하고 Secondary Index 를 사용하여 조회를 더 자유롭게 할 수 있다. DynamoDB Streams 를 활용하여 DynamoDB 의 변경 이벤트를 감지할 수 있다.


Tables, Items, 그리고 Attributes

 아래 설명은 DynamoDB 의 기본 컴포넌트에 대한 것이다.

  • Tables - 다른 데이터베이스들과 비슷하게 DynamoDB 도한 데이터를 테이블에 저장한다. Table 은 데이터의 집합이다. 예를들어, People 이라는 이름의 테이블은 친구, 가족 혹은 관심있는 다른 사람들의 연락처 데이터를 저장할 수 있다. Cars 테이블은 사람들이 운전하는 탈것 에 대한 데이터를 저장한다. 
  • Items - 각 테이블은 0개 이상의 Item을 갖는다. Item 은 Attribute 의 모임이다. Attribute 는 서로 다른 아이템들을 구분지을 수 있다. People 테이블에서 각 아이템들은 사람을 나타낸다. Cars 테이블에서는 하나의 탈것을 나타낸다. DynamoDB 의 아이템은 다른 데이터베이스의 Rows, Records, Tuples 과 비슷하다. DynamoDB 에서 테이블에 저장할 수 있는 Item 은 무한하다.
  • Attributes - 각 Item 은 한개 이상의 Attribute 로 구성된다. Attribute 는 더 이상 쪼갤 수 없는 핵심적인 데이터 요소이다. 예를들어, People 테이브에는 PersonID, LastName, FirstName 등등의  Attribute 를 포함하고 있다. Department 의 경우에는, DepartmentID, Name, Manager 등등이 있다. DynamoDB 의 Attribute 는 다른 데이터베이스 시스템의 Field 혹은 Column 과 비슷하다.

아래 다이어그램은 people 테이블의 Item 과 Attribute 를 보여준다.

People

{
    "PersonID": 101,
    "LastName": "Smith",
    "FirstName": "Fred",
    "Phone": "555-4321"
}

{
    "PersonID": 102,
    "LastName": "Jones",
    "FirstName": "Mary",
    "Address": {
                "Street": "123 Main",
                "City": "Anytown",
                "State": "OH",
                "ZIPCode": 12345
    }
}

{
    "PersonID": 103,
    "LastName": "Stephens",
    "FirstName": "Howard",
    "Address": {
                "Street": "123 Main",
                "City": "London",                                    
                "PostalCode": "ER3 5K8"
    },
    "FavoriteColor": "Blue"
}

People 테이블에 대한 설명

  • 각 아이템들은 Primary Key 라고 불리는 고유 식별자가 존재한다. People 테이블의 Primary Key 는 하나의 Attribute 로 구성되었다. (PersonID)
  • People 테이블은 스키마가 없기 때문에, Attribute 나 데이터 타입을 미리 정의할 필요가 없다. 각 아이템은 서로 다른 Attribute 를 가질 수 있다.
  • 대부분의 Attribute 는 방향성이 없는 스칼라이다. 따라서 하나의 값만 가질 수 있다. 스칼라의 대표적인 예는 String 과 Number 이다.
  • 어떤 Item 은 Nested Attribute 를 가지고 있다 (Address). DynamoDB 는 32 단계 까지 Nested Attribute 를 제공한다. 

아래는 또 다른 예제인 Music 테이블이다.

Music

{
    "Artist": "No One You Know",
    "SongTitle": "My Dog Spot",
    "AlbumTitle": "Hey Now",
    "Price": 1.98,
    "Genre": "Country",
    "CriticRating": 8.4
}

{
    "Artist": "No One You Know",
    "SongTitle": "Somewhere Down The Road",
    "AlbumTitle": "Somewhat Famous",
    "Genre": "Country",
    "CriticRating": 8.4,
    "Year": 1984
}

{
    "Artist": "The Acme Band",
    "SongTitle": "Still in Love",
    "AlbumTitle": "The Buck Starts Here",
    "Price": 2.47,
    "Genre": "Rock",
    "PromotionInfo": {
        "RadioStationsPlaying": {
            "KHCR",
            "KQBX",
            "WTNR",
            "WJJH"
        },
        "TourDates": {
            "Seattle": "20150622",
            "Cleveland": "20150630"
        },
        "Rotation": "Heavy"
    }
}

{
    "Artist": "The Acme Band",
    "SongTitle": "Look Out, World",
    "AlbumTitle": "The Buck Starts Here",
    "Price": 0.99,
    "Genre": "Rock"
}

Music 테이블에 대한 설명:

  • Music 테이블의 Primary Key 는 두개의 Attribute 로 구성되어있다 (Artist & Song Title). 테이블의 각 아이템은 이 두가지 Attribute 를 필수로 가지고 있어야 한다. Artist & Song Title 의 조합은 테이블내에서 아이템을 구별할 수 있게 해준다.
  • Music 테이블은 스키마가 없기 때문에, Attribute 나 데이터 타입을 미리 정의할 필요가 없다. 각 아이템은 서로 다른 Attribute 를 가질 수 있다.
  • 어떤 Item 은 Nested Attribute 를 가지고 있다 (PromotionInfo). DynamoDB 는 32 단계 까지 Nested Attribute 를 제공한다.

Primary key

 테이블을 생성할때 테이블 이름과 테이블의 Primary Key 를 지정해야한다. Primary Key 는 테이블내에서 각 아이템을 구별하기 때문에 아이템들은 같은 Primary Key 를 가질 수 없다.

 

 DynamoDB 는 두가지 종류의 Primary Key 를 제공한다:

  • Partiton Key - 하나의 Attribute 로 구성된 간단한 Primary key 이다. DynamoDB 는 내부의 hash function 의 input 으로 parition key 를 사용한다. hash function 의 output 은 해당 아이템이 어느 파티션에 저장될지를 결정한다. Partition Key 만 가지고 있는 테이블의 아이템들은 같은 Partition Key 를 가질 수 없다. Person 테이블은 Simple Primary Key 의 예제이다 (PersonID). PersonID 를 사용하여 해당 Item 의 데이터에 직접적으로 접근할 수 있다.
  • Partiton key 와 sort key - Composite Primary Key 에 따르면, 이 종류의 Key 는 두개의 Attribute로 구성된다. 첫번째 Attribute 는 Parition Key 이고 두번째 Attribute 는 Sort Key 이다. DynamoDB 는 Hash Function 의 Input 으로 Parition Key 를 사용한다. Hash Function 의 결과는 아이템을 어느 파티션에 저장할지를 결정한다. 같은 Partition Key 를 가지는 아이템들은 같은 파티션에 저장되고 Sort key 값에 따라서 정렬된다. Partition Key 와 Sort key 를 가진 테이블은 같은 파티션키를 가진 데이터가 존재할 수 있다. 하지만, 이 아이템들은 서로 다른 Sort Key 를 갖는다. Music 테이블은 Composite Primary Key 를 가진 예제이다. Artist & SongTitle 값이 있다면 Item 에 직접적으로 접근할 수 있다. Composite Primary Key 는 데이터 조회에 있어 추가적인 유연성을 제공한다. 예를들어, Aritist 만을 조건으로 DynamoDB 에 조회할 경우에 DynamoDB 는 해당 Aritist 를 갖는 모든 데이터를 리턴한다. 특정 Aritist 의 Song 중에 하나만을 조회하고 싶다면 SontTitle 또한 조회조건에 포함시켜야 한다.
Note
 
Partition Key 는 Hash Attribute 로도 불린다. Hash Attribute 라는 용어는 Parition Key 에 따라서 각 파티션에 데이터 분배에 사용된다. 

 Sort key 는 Range Attribute 로도 불린다. Range Attribute 라는 용어는 Sort key 값에 따라서 같은 파티션에 아이템들을 가깝게 저장하도록하며 Sort key 기준으로 정렬한다.

 각각의 Primary Key Attribute 는 스칼라이여야 한다(하나의 값만 가질 수 있다는 의미). Primary Key 는 String, Number, Binary 타입만을 가질 수 있다. Key 가 아닌 Attribute 의 타입에는 제한이 없다.


Secondary Indexes

  Table 에 하나 이상의 Secondary index 를 생성할 수 있다. Secondary Index 는 Primary Key 에 대한 쿼리 외에도 조회가 가능하도록 한다. DynamoDB 에서 Index 는 필수가 아니다. 하지만 Index 는 프로그램이 데이터를 조회함에 있어서 더 자유롭고 유연하도록 도와준다. Secondary Index 를 생성한 후에는, 이제까지 해왔던 것과 같은 방법으로 Index 를 통하여 데이터를 읽어올 수 있다.

 

 DynamoDB 는 두가지 Index 를 지원한다:

  • Global Secondary Index - 테이블의 기존 Parition Key 와 Sort Key 와 다른 키들로 구성된 Index
  • Local Secondary Index - 테이블의 기존 Partition Key 와는 동일하고 다른 Sort Key 를 갖는 Index

DynamoDB 의 각 테이블은 20개의 Global Secondary Index 한도를 가지고 5 개의 Local Secondary Index 의 한도를 갖는다. 

 

 예를들어 Music 테이블에서, Artist (Partition Key) 를 이용하여 조회가 가능했고 Aritist (Partiton Key) 와 SongTitle(Sort key) 로 조회할 수 있다. 하지만 Genre 혹은 Album Title 과 같은 Attribute 로 조회하고 싶다면 어떻게 해야할까. Genre 와 AlbumTitle 로 Index 를 생성하면 이전에 조회했던 것 처럼 조회가 가능하다.

 

 아래 다이어그램은 GenreAlubumTitle 로 불리는 Index 를 포함한 Music 테이블의 예제를 보여준다. Index 에서 Genre 는 Parition  Key 이고 AlbumTitle 은 Sort key 이다.

 

Music Table GenreAlbumTitle
{
    "Artist": "No One You Know",
    "SongTitle": "My Dog Spot",
    "AlbumTitle": "Hey Now",
    "Price": 1.98,
    "Genre": "Country",
    "CriticRating": 8.4
}            
{
    "Genre": "Country",
    "AlbumTitle": "Hey Now",
    "Artist": "No One You Know",
    "SongTitle": "My Dog Spot"
}
{
    "Artist": "No One You Know",
    "SongTitle": "Somewhere Down The Road",
    "AlbumTitle": "Somewhat Famous",
    "Genre": "Country",
    "CriticRating": 8.4,
    "Year": 1984
}
{
    "Genre": "Country",
    "AlbumTitle": "Somewhat Famous",
    "Artist": "No One You Know",
    "SongTitle": "Somewhere Down The Road"
}
{
    "Artist": "The Acme Band",
    "SongTitle": "Still in Love",
    "AlbumTitle": "The Buck Starts Here",
    "Price": 2.47,
    "Genre": "Rock",
    "PromotionInfo": {
        "RadioStationsPlaying": {
            "KHCR",
            "KQBX",
            "WTNR",
            "WJJH"
        },
        "TourDates": {
            "Seattle": "20150622",
            "Cleveland": "20150630"
        },
        "Rotation": "Heavy"
    }
}
{
    "Genre": "Rock",
    "AlbumTitle": "The Buck Starts Here",
    "Artist": "The Acme Band",
    "SongTitle": "Still In Love"
}
{
    "Artist": "The Acme Band",
    "SongTitle": "Look Out, World",
    "AlbumTitle": "The Buck Starts Here",
    "Price": 0.99,
    "Genre": "Rock"
}
{
    "Genre": "Rock",
    "AlbumTitle": "The Buck Starts Here",
    "Artist": "The Acme Band",
    "SongTitle": "Look Out, World"
}

 GenereAlbumTitle 인덱스에 대한 설명:

  • 모든 Index 는 테이블에 속하며 이 테이블은 인덱스의 Base Table 이라고 불린다. Music 은 GenereAlbumTitle 의 Base Table 이다.
  • DynamoDB 는 인덱스들을 자동으로 관리한다. Base Table 에서 아이템에 대해서 CRUD 가 발생할때 DynamoDB 는 같은 작업을 해당 테이블에 속해있는 모든 Index 에 대해서도 처리한다.
  • Index 를 생성할때 어떤 Attribute 가 Base Table 로 부터 복사되거나 예상될지 결정해야한다. DynamoDB 는 Base Table 들의 Key 는 Index 에 포함되도록 예상한다. GenreAlbumTitle 인덱스를 예를들면, Music 테이블의 Key 들은 인덱스에 포함되었다.

GenreAlbumTitle 인덱스를 통하여 특정 Genre (예를 들어 모든 Rock 앨범) 의 모든 앨범을 조회할 수 있다. 또한, 특정 장르내에 Album Title 을 갖는 모든 앨범을 조회할 수 있다 (예를들어, 모든 Country 장르 앨범중에 H 로 타이틀이 시작하는 앨범)


DynamoDB Streams

 DynamoDB Stream 은 DynamoDB 의 데이터 변경을 감지하기 위한 기능이다. 이 이벤트는 데이터가 변경되었을때 준실시간으로 발생하며 수정된 순서대로 이벤트가 발생된다.

 

 각 이벤트는 Stream Record 로 나타내진다. 테이블의 Stream 을 호라성화하면, DynamoDB Stream 은 아래 이벤트가 발생하였을때  Stream Record 를 쓰게된다. 

  • Item 이 추가됨: Stream 은 모든 Attribute 를 포함한 전체 아이템을 수집.
  • Item 이 업데이트됨: Stream 은 수정된 Attribute 의 "before" 와 "after" 를 수집.
  • Item 이 삭제됨 : Item 이 삭제되기 전에 전체 데이터를 수집.

각 Stream Record 는 테이블의 이름, 이벤트 시간과 같은 메타 데이터를 갖는다. Stream Record 는 24 시간동안 유지되었다가 자동으로 Stream 에서 삭제된다. 

 

 DynamoDB Stream 은 AWS Lambda 와 함께 사용할 수 있다. Stream 에 이벤트가 발생하였을때 Lambda 를 트리거할 수 있다. 예를들어, 회사의 고객정보를 가지고있는 Customer 테이블이 있다고 가정해보자. 새로운 고객들에게 "welcome" 메일을 보내고 싶다면, Customer 테이블의 Stream 을 활성화 한 후에 Labmda Function 과 연동시킬 수 있다. Lambda 는 매번 DynamoDB 에 Item 이 추가되었을때 동작하게되며, 수정, 삭제시에는 동작하지 않는다. EmailAddress Attribute 가 있는 아이템만 해당 주소로 이메일을 보내기 위하여 Labmda 를 실행한다.

Note
 예를들어, 마지막 고객인 Craig Roe 는 EmailAddress 가 없기 때문에 이메일을 받지 않을 것이다.

 추가로, DynamoDB Stream 은 AWS 리전 데이터 복제, 시각화, 데이터 분석등을 지원하는 kinesis 와 연동할 수 있다.

 

 

출처 : https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html