

# Amazon DynamoDB: 작동 방식
<a name="HowItWorks"></a>

다음 섹션에서 Amazon DynamoDB 서비스 구성 요소 및 요소 간 상호 작용 방식을 간단히 설명합니다.

**Topics**
+ [DynamoDB에 대한 치트 시트](CheatSheet.md)
+ [Amazon DynamoDB의 핵심 구성 요소](HowItWorks.CoreComponents.md)
+ [DynamoDB API](HowItWorks.API.md)
+ [Amazon DynamoDB에서 지원되는 데이터 형식 및 이름 지정 규칙](HowItWorks.NamingRulesDataTypes.md)
+ [DynamoDB 테이블 클래스](HowItWorks.TableClasses.md)
+ [DynamoDB의 파티션 및 데이터 배포](HowItWorks.Partitions.md)
+ [SQL에서 NoSQL로 전환하는 방법 알아보기](SQLtoNoSQL.md)
+ [Amazon DynamoDB 학습 리소스 및 도구](AdditionalResources.md)

# DynamoDB에 대한 치트 시트
<a name="CheatSheet"></a>

이 치트 시트는 Amazon DynamoDB 및 다양한 AWS SDK를 사용하기 위한 빠른 참조를 제공합니다.

## 초기 설정
<a name="CheatSheet.InitialSetup"></a>

1. [에 가입합니다.AWS](SettingUp.DynamoWebService.html#SettingUp.DynamoWebService.SignUpForAWS)

1. 프로그래밍 방식으로 DynamoDB에 액세스하려면 [AWS 액세스 키를 얻습니다](SettingUp.DynamoWebService.html#SettingUp.DynamoWebService.GetCredentials).

1. [DynamoDB 보안 인증 정보를 구성합니다](SettingUp.DynamoWebService.html#SettingUp.DynamoWebService.ConfigureCredentials).

**다음 사항도 참조하세요.**
+ [DynamoDB 설정(웹 서비스)](SettingUp.DynamoWebService.html)
+ [DynamoDB 시작하기](GettingStartedDynamoDB.html)
+ [핵심 구성 요소의 기본 개요](HowItWorks.CoreComponents.html)

 

## SDK 또는 CLI
<a name="CheatSheet.Platform"></a>

선호하는 [SDK](sdk-general-information-section.html)를 선택하거나 [AWS CLI](/cli/latest/index.html)를 설정합니다.

**참고**  
Windows에서 AWS CLI를 사용하는 경우 따옴표 안에 없는 백슬래시(\$1)는 캐리지 리턴으로 처리됩니다. 또한 다른 따옴표 안에 있는 따옴표와 중괄호는 모두 이스케이프 처리해야 합니다. 예를 보려면 다음 섹션의 "테이블 생성"에서 **Windows** 탭을 참조하세요.

**다음 사항도 참조하세요.**
+ [DynamoDB와 함께 AWS CLI 사용](Tools.CLI.html)
+ [DynamoDB 시작하기 - 2단계](getting-started-step-2.html)

## 기본 작업
<a name="CheatSheet.BasicActions"></a>

이 섹션에서는 기본 DynamoDB 태스크를 위한 코드를 제공합니다. 이러한 태스크에 대한 자세한 내용은 [DynamoDB 및 AWS SDK 시작하기](GettingStarted.html)를 참조하세요.

### 테이블 생성
<a name="CheatSheet.BasicActions.CreateTable"></a>

------
#### [ Default ]

```
aws dynamodb create-table \
    --table-name Music \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
    --key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \
    --billing-mode PAY_PER_REQUEST \
    --table-class STANDARD
```

------
#### [ Windows ]

```
aws dynamodb create-table ^
    --table-name Music ^
    --attribute-definitions ^
        AttributeName=Artist,AttributeType=S ^
        AttributeName=SongTitle,AttributeType=S ^
    --key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE ^
    --billing-mode PAY_PER_REQUEST ^
    --table-class STANDARD
```

------

### 테이블에 항목 쓰기
<a name="CheatSheet.BasicActions.WriteItem"></a>

```
aws dynamodb put-item \ --table-name Music \ --item file://item.json
```

### 테이블에서 항목 읽기
<a name="CheatSheet.BasicActions.ReadItem"></a>

```
aws dynamodb get-item \ --table-name Music \ --item file://item.json
```

### 테이블에서 항목 삭제
<a name="CheatSheet.BasicActions.DeleteItem"></a>

```
aws dynamodb delete-item --table-name Music --key file://key.json
```

### 테이블 쿼리
<a name="CheatSheet.BasicActions.QueryTable"></a>

```
aws dynamodb query --table-name Music 
--key-condition-expression "ArtistName=:Artist and SongName=:Songtitle"
```

### 테이블 삭제
<a name="CheatSheet.BasicActions.DeleteTable"></a>

```
aws dynamodb delete-table --table-name Music
```

### 테이블 이름 나열
<a name="CheatSheet.BasicActions.ListTableNames"></a>

```
aws dynamodb list-tables
```

## 이름 지정 규칙
<a name="CheatSheet.NamingRules"></a>
+ 모든 이름은 UTF-8로 인코딩되어야 하며, 대소문자를 구분합니다.
+ 테이블 이름 및 인덱스 이름은 3\$1255자로 이루어져야 하며, 다음 문자만 포함할 수 있습니다.
  + `a-z`
  + `A-Z`
  + `0-9`
  + `_`(밑줄)
  + `-`(하이픈)
  + `.`(점)
+ 속성 이름은 1자 이상이고 크기가 64KB 미만이어야 합니다.

자세한 내용은 [이름 지정 규칙](HowItWorks.NamingRulesDataTypes.html)을 참조하세요.

## 서비스 할당량 기본 사항
<a name="CheatSheet.ServiceBasics"></a>

**읽기 및 쓰기 단위**
+ **읽기 용량 단위(RCU)** – 초당 강력히 일관된 읽기 1회 또는 초당 최종 읽기 일관성 2회(크기가 최대 4KB인 항목).
+ **쓰기 용량 단위(WCU)** – 초당 쓰기 1회(크기가 최대 1KB인 항목)

**테이블 제한**
+ **테이블 크기** – 테이블 크기에는 실질적인 제한이 없습니다. 테이블의 항목 수 또는 바이트 수에는 제약이 없습니다.
+ **테이블 개수** – 임의의 AWS 계정에 대해 AWS 리전당 테이블 2,500개의 초기 할당량이 있습니다.
+ **쿼리 및 스캔의 페이지 크기 제한** – 페이지당, 쿼리 또는 스캔당 1MB로 제한됩니다. 테이블에서 쿼리 파라미터 또는 스캔 작업을 수행한 결과 데이터가 1MB를 초과하는 경우 DynamoDB는 초기 일치 항목을 반환합니다. 또한 새 요청에서 다음 페이지를 읽는 데 사용할 수 있는 `LastEvaluatedKey` 속성도 반환합니다.

**인덱스**
+ **로컬 보조 인덱스(LSI)** - 최대 5개의 로컬 보조 인덱스를 정의할 수 있습니다. LSI는 주로 인덱스가 기본 테이블과 강한 일관성을 가져야 할 때 유용합니다.
+ **글로벌 보조 인덱스(GSI)** – 기본적으로 테이블당 20개의 글로벌 보조 인덱스 할당량이 있습니다.
+ **테이블당 프로젝션된 보조 인덱스 속성** – 테이블의 모든 로컬 및 글로벌 보조 인덱스에 속성을 총 100개까지 프로젝션할 수 있습니다. 사용자 지정 프로젝션 속성에만 이 제한이 적용됩니다.

**파티션 키**
+ 파티션 키 값의 최소 길이는 1바이트입니다. 최대 길이는 2,048바이트입니다.
+ 고유 파티션 키 값의 수는 테이블 또는 보조 인덱스에 대해 실제로 제한이 없습니다.
+ 정렬 키 값의 최소 길이는 1바이트입니다. 최대 길이는 1,024바이트입니다.
+ 일반적으로 파티션 키 값당 고유 정렬 키 값의 수는 실제로 제한이 없습니다. 보조 인덱스를 포함하는 테이블은 예외입니다.

보조 인덱스, 파티션 키 설계 및 정렬 키 설계에 대한 자세한 내용은 [모범 사례](best-practices.html)를 참조하세요.

**일반적으로 사용되는 데이터 유형의 제한**
+ **문자열** – 문자열 길이는 최대 항목 크기 400KB의 제한을 받습니다. 문자열은 UTF-8 이진수 인코딩을 사용하는 유니코드입니다.
+ **숫자** – 숫자는 소수점 아래 최대 38자리의 양수, 음수 또는 0이 될 수 있습니다.
+ **이진수** – 이진수 길이는 최대 항목 크기 400KB의 제한을 받습니다. 이진 속성을 처리하는 애플리케이션에서는 데이터를 DynamoDB로 보내기 전에 base64로 인코딩해야 합니다.

지원되는 데이터 형식의 목록은 [데이터 형식](HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes)을 참조하세요. 자세한 내용은 [Service Quotas](ServiceQuotas.html#limits-items)를 참조하세요.

### 항목, 속성 및 표현식 파라미터
<a name="CheatSheet.ServiceBasics.Misc"></a>

DynamoDB에서 최대 항목 크기가 400KB를 초과할 수 없습니다. 여기에는 속성 이름 이진 길이(UTF-8 길이)와 속성 값 이진 길이(UTF-8 길이)가 모두 포함됩니다. 속성 이름은 크기 제한에 포함됩니다.

목록, 맵 또는 집합 내 값의 수에는 제한이 없습니다. 단, 값을 포함하는 항목이 400KB 항목 크기 제한을 초과하지 않아야 합니다.

표현식 파라미터의 경우 표현식 문자열의 최대 길이는 4KB입니다.

항목 크기, 속성 및 표현식 파라미터에 대한 자세한 내용은 [Service Quotas](ServiceQuotas.html#limits-items)를 참조하세요.

## 추가 정보
<a name="CheatSheet.FurtherInfo"></a>
+ [보안](security.html)
+ [모니터링 및 로깅](monitoring.html)
+ [스트림 작업](streamsmain.html)
+ [백업](Backup-and-Restore.html) 및 [특정 시점으로 복구](Point-in-time-recovery.html)
+ [다른 AWS 서비스와 통합](OtherServices.html) 
+ [API 참조](/amazondynamodb/latest/APIReference/Welcome.html)
+ [아키텍처 센터: 데이터베이스 모범 사례](https://aws.amazon.com/architecture/databases/)
+ [자습서 비디오](https://youtu.be/Mw8wCj0gkRc)
+ [DynamoDB 포럼](https://repost.aws/search/questions?globalSearch=dynamodb)

# Amazon DynamoDB의 핵심 구성 요소
<a name="HowItWorks.CoreComponents"></a>

DynamoDB에서 테이블, 항목 및 속성이 작업하는 핵심 구성 요소입니다. *테이블*은 *항목*의 컬렉션이고 각 항목은 *속성*의 컬렉션입니다. DynamoDB는 프라이머리 키를 사용하여 테이블의 각 항목을 고유하게 식별합니다. DynamoDB Streams를 사용해 DynamoDB 테이블의 데이터 수정 이벤트를 캡처할 수 있습니다.

 DynamoDB에는 제한이 있습니다. 자세한 내용은 [Amazon DynamoDB의 할당량](ServiceQuotas.md) 섹션을 참조하세요.

다음 비디오에서는 테이블, 항목 및 속성에 대해 소개합니다.

[테이블, 항목 및 속성](https://www.youtube.com/embed/Mw8wCj0gkRc)

## 테이블, 항목 및 속성
<a name="HowItWorks.CoreComponents.TablesItemsAttributes"></a>

![\[각 DynamoDB 테이블에는 하나 이상의 속성으로 구성된 항목이 0개 이상 포함되어 있습니다.\]](http://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/images/HowItWorksTables-2024.png)


다음은 기본 DynamoDB 구성 요소입니다.
+ **테이블** - 다른 데이터베이스 시스템과 마찬가지로 DynamoDB는 데이터를 테이블에 저장합니다. *테이블*은 데이터의 집합입니다. 예를 들어, 친구, 가족 또는 기타 관심 있는 사람에 대한 정보를 저장하는 데 사용할 수 있는 *People*이라는 예제 테이블을 살펴 봅니다. 또한 *Cars* 테이블에 사람들이 운전하는 차량에 대한 정보를 저장할 수도 있습니다.
+ **항목** - 각 테이블에는 0개 이상의 항목이 있습니다. *항목*은 모든 기타 항목 중에서 고유하게 식별할 수 있는 속성들의 집합입니다. *People* 테이블에서 각 항목은 한 사람을 나타냅니다. *Cars* 테이블의 경우 각 항목은 차량 한 대를 나타냅니다. DynamoDB의 항목은 여러 가지 면에서 다른 데이터베이스 시스템의 행, 레코드 또는 튜플과 유사합니다. DynamoDB에서는 테이블에 저장할 수 있는 항목의 수에 제한이 없습니다.
+ **속성** - 각 항목은 하나 이상의 속성으로 구성됩니다. *속성*은 기본적인 데이터 요소로서 더 이상 나뉠 필요가 없는 것입니다. 예를 들어 *People* 테이블의 항목에는 *PersonID*, *LastName*, *FirstName* 등의 속성이 있습니다. *Department* 테이블의 경우 항목에 *DepartmentID*, *Name*, *Manager* 등의 속성이 있을 수 있습니다. DynamoDB의 속성은 여러 가지 면에서 다른 데이터베이스 시스템의 필드 또는 열과 유사합니다.

다음 다이어그램은 몇 가지 예제 항목과 속성이 있는 *People*이라는 테이블을 보여 줍니다.

```
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* 테이블에 대해 다음을 알아 두세요.
+ 테이블의 각 항목에는 항목을 테이블의 다른 모든 항목과 구별해 주는 고유 식별자인 기본 키가 있습니다. *People* 테이블에서 기본 키는 한 개의 속성(*PersonID*)으로 구성됩니다.
+ 기본 키를 제외하고, *People* 테이블에는 스키마가 없습니다. 이는 속성이나 데이터 형식을 미리 정의할 필요가 없음을 의미합니다. 각 항목에는 자체의 고유 속성이 있을 수 있습니다.
+ 대부분의 속성은 *스칼라*인데, 이는 하나의 값만 가질 수 있다는 의미입니다. 문자열 및 숫자가 스칼라의 일반적인 예입니다.
+ 일부 항목에는 중첩된 속성(*Address*)이 있습니다. DynamoDB는 최대 32개 깊이 수준까지 중첩된 속성을 지원합니다.

다음은 음악 파일을 추적하는 데 사용할 수 있는 *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*의 기본 키는 두 개의 속성(*Artist* 및 *SongTitle*)으로 구성되어 있습니다. 테이블의 각 항목이 이러한 두 속성을 가지고 있어야 합니다. *Artist*와 *SongTitle*의 조합은 테이블의 각 항목을 다른 모든 항목과 구별해 줍니다.
+ 기본 키를 제외하고, *Music* 테이블에는 스키마가 없습니다. 이는 속성이나 데이터 형식을 미리 정의할 필요가 없음을 의미합니다. 각 항목에는 자체의 고유 속성이 있을 수 있습니다.
+ 항목 중 하나에 중첩된 속성(*PromotionInfo*)이 있는데, 이 속성에 다른 중첩된 속성이 포함되어 있습니다. DynamoDB는 최대 32개 깊이 수준까지 중첩된 속성을 지원합니다.

 자세한 내용은 [DynamoDB의 테이블 및 데이터 작업](WorkingWithTables.md) 섹션을 참조하세요.

## 프라이머리 키
<a name="HowItWorks.CoreComponents.PrimaryKey"></a>

테이블을 생성할 때는 테이블 이름 외에도 테이블의 기본 키를 지정해야 합니다. 프라이머리 키는 테이블의 각 항목을 나타내는 고유 식별자입니다. 따라서 두 항목이 동일한 키를 가질 수는 없습니다.

DynamoDB는 두 가지의 기본 키를 지원합니다.
+ **파티션 키** - *파티션 키*로 알려진 하나의 속성으로 구성되는 단순 기본 키

  DynamoDB는 내부 해시 함수에 대한 입력으로 파티션 키 값을 사용합니다. 해시 함수 출력에 따라 항목을 저장할 파티션(DynamoDB 내부의 물리적 스토리지)이 결정됩니다.

   파티션 키로만 구성되어 있는 테이블에서는 어떤 두 개의 테이블 항목도 동일한 파티션 키 값을 가질 수 없습니다.

  [테이블, 항목 및 속성](#HowItWorks.CoreComponents.TablesItemsAttributes)에 설명된 *People* 테이블은 단순 기본 키(*PersonID*)를 사용하는 테이블의 예입니다. *People* 테이블의 모든 항목은 해당 항목의 *PersonId* 값을 제공하여 직접 액세스할 수 있습니다.
+ **파티션 키 및 정렬 키** - *복합 기본 키*로 지칭되는 이 형식의 키는 두 개의 속성으로 구성됩니다. 첫 번째 속성은 *파티션 키*이고, 두 번째 속성은 *정렬 키*입니다.

  DynamoDB는 내부 해시 함수에 대한 입력으로 파티션 키 값을 사용합니다. 해시 함수 출력에 따라 항목을 저장할 파티션(DynamoDB 내부의 물리적 스토리지)이 결정됩니다. 파티션 키 값이 동일한 모든 항목은 정렬 키 값을 기준으로 정렬되어 함께 저장됩니다.

  파티션 키와 정렬 키로 구성되어 있는 테이블에서는 여러 항목이 동일한 파티션 키 값을 가질 수 있습니다. 그러나 이러한 아이템의 정렬 키 값은 달라야 합니다.

  [테이블, 항목 및 속성](#HowItWorks.CoreComponents.TablesItemsAttributes)에 설명된 *Music* 테이블은 복합 기본 키(*Artist* 및 *SongTitle*)를 사용하는 테이블의 예입니다. *Music* 테이블의 모든 항목은 해당 항목의 *Artist* 및 *SongTitle* 값을 제공하는 경우 직접 액세스할 수 있습니다.

  복합 기본 키를 사용하면 보다 유연하게 데이터를 쿼리할 수 있습니다. 예를 들어, *Artist* 값만 제공하는 경우, DynamoDB는 해당 아티스트의 모든 노래를 검색합니다. *Artist* 값과 함께 *SongTitle* 값 범위를 입력하여 특정 아티스트의 노래 중 일부만 검색할 수도 있습니다.

**참고**  
항목의 파티션 키를 *해시 속성*이라고도 합니다. *해시 속성*이라는 용어는 파티션 키 값에 따라 파티션에 데이터 항목을 고르게 분산하는 DynamoDB의 내부 해시 함수를 사용하는 것에서 유래합니다.  
항목의 정렬 키를 *범위 속성*이라고도 합니다. *범위 속성*이라는 용어는 DynamoDB가 파티션 키가 동일한 항목을 정렬 키 값을 기준으로 정렬된 순서로 물리적으로 서로 가깝게 저장하는 방식에서 유래합니다.

각 기본 키 속성은 스칼라여야 합니다(즉, 단일 값만 가질 수 있음). 기본 키 속성에 허용되는 데이터 형식은 문자열, 숫자 또는 이진수뿐입니다. 다른 키가 아닌 속성에는 이러한 제한이 없습니다.

## 보조 인덱스
<a name="HowItWorks.CoreComponents.SecondaryIndexes"></a>

테이블에서 하나 이상의 보조 인덱스를 생성할 수 있습니다. *보조 인덱스*를 사용하면 기본 키에 대한 쿼리는 물론이고 대체 키를 사용하여 테이블의 데이터도 쿼리할 수 있습니다. DynamoDB에서는 인덱스를 사용하지 않아도 되지만, 인덱스를 사용하면 데이터를 쿼리할 때 애플리케이션에 보다 많은 유연성을 제공합니다. 테이블에서 보조 인덱스를 생성한 후에는 테이블에서 데이터를 읽는 것과 같은 방식으로 인덱스에서 데이터를 읽을 수 있습니다.

DynamoDB는 다음과 같이 두 가지 종류의 인덱스를 지원합니다.
+ 글로벌 보조 인덱스 - 파티션 키 및 정렬 키가 테이블과 다를 수 있는 인덱스입니다. 글로벌 보조 인덱스의 프라이머리 키 값은 고유할 필요가 없습니다.
+ 로컬 보조 인덱스 - 기본 테이블과 파티션 키는 동일하지만 정렬 키가 다른 인덱스입니다.

DynamoDB에서 글로벌 보조 인덱스(GSI)는 테이블 전체에 걸쳐 있는 인덱스이므로 모든 파티션 키를 쿼리할 수 있습니다. 로컬 보조 인덱스(LSI)는 기본 테이블과 파티션키는 동일하지만 정렬 키는 다른 인덱스입니다.

DynamoDB의 각 테이블에는 글로벌 보조 인덱스 20개(기본 할당량)와 로컬 보조 인덱스 5개의 할당량이 있습니다.

앞에 나온 *Music* 테이블 예제에서는 *Artist*(파티션 키)를 기준으로 또는 *Artist*와 *SongTitle*(파티션 키와 정렬 키)을 기준으로 데이터 항목을 쿼리할 수 있습니다. *Genre* 및 *AlbumTitle*로도 데이터를 쿼리하고 싶다면 어떻게 해야 할까요? 그렇게 하려면 *Genre* 및 *AlbumTitle*에 대해 인덱스를 생성한 후 *Music* 테이블을 쿼리한 방법대로 인덱스를 쿼리하면 됩니다.

다음 다이어그램은 *Music* 테이블과 *GenreAlbumTitle*이라는 새 인덱스를 보여 줍니다. 인덱스에서 *Genre*는 파티션 키이고, *AlbumTitle*은 정렬 키입니다.


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

*GenreAlbumTitle* 테이블에 대해 다음을 알아 두세요.
+ 모든 인덱스는 테이블에 속해 있는데, 이를 인덱스의 *기본 테이블*이라고 합니다. 앞의 예제에서 *Music*은 *GenreAlbumTitle* 인덱스의 기본 테이블입니다.
+ DynamoDB는 인덱스를 자동으로 유지 관리합니다. 기본 테이블의 항목을 추가, 업데이트 또는 삭제하면 DynamoDB는 해당 테이블에 속하는 모든 인덱스에서 해당 항목을 추가, 업데이트 또는 삭제합니다.
+ 인덱스를 생성할 때는 기본 테이블에서 인덱스로 복사하거나 *프로젝션*할 속성을 지정합니다. 적어도 DynamoDB는 기본 테이블의 키 속성을 인덱스로 프로젝션합니다. `GenreAlbumTitle`의 경우가 그러한데, `Music` 테이블의 키 속성만 인덱스로 프로젝션됩니다.

*GenreAlbumTitle* 인덱스를 쿼리하여 특정 장르의 앨범을 모두 찾을 수 있습니다(예: 모든 *Rock* 앨범). 또한 인덱스를 쿼리하여 특정 앨범 제목이 있는 특정 장르에 속하는 모든 앨범을 찾을 수도 있습니다(예: 제목이 알파벳 H로 시작하는 모든 *Country* 앨범).

자세한 내용은 [DynamoDB에서 보조 인덱스를 사용하여 데이터 액세스 개선](SecondaryIndexes.md) 섹션을 참조하세요.

## DynamoDB Streams
<a name="HowItWorks.CoreComponents.Streams"></a>

DynamoDB Streams는 DynamoDB 테이블의 데이터 수정 이벤트를 캡처하는 선택적 기능입니다. 이러한 이벤트에 대한 데이터가 이벤트가 발생한 순서대로 거의 실시간으로 스트림에 표시됩니다.

각 이벤트는 *스트림 레코드*에 의해 나타납니다. 테이블에서 스트림을 활성화하면 다음과 같은 이벤트 중 하나가 발생할 때마다 DynamoDB Streams가 스트림 레코드를 기록합니다.
+ 테이블에 새로운 항목이 추가되면 스트림이 해당 속성을 모두 포함하여 전체 항목의 이미지를 캡처합니다.
+ 항목이 업데이트되면 스트림이 항목에서 수정된 속성의 "사전" 및 "사후" 이미지를 캡처합니다.
+ 테이블에서 항목이 삭제되면 스트림이 항목이 삭제되기 전에 전체 항목의 이미지를 캡처합니다.

각 스트림 레코드에는 또한 테이블의 이름, 이벤트 타임스탬프 및 다른 메타데이터가 포함되어 있습니다. 스트림 레코드의 수명은 24시간이며, 24시간이 지나면 스트림에서 자동으로 제거됩니다.

DynamoDB Streams를 AWS Lambda와 함께 사용하면 *트리거*, 즉 관심 있는 이벤트가 스트림에 나타날 때마다 자동으로 실행되는 코드를 생성할 수 있습니다. 예를 들어, 회사의 고객 정보가 들어 있는 *Customers* 테이블을 생각해 볼 수 있습니다. 새 고객마다 "환영" 이메일을 보내려고 한다고 가정해 보세요. 해당 테이블에 스트림을 활성화한 다음, 스트림을 Lambda 함수와 연결할 수 있습니다. Lambda 함수는 새로운 스트림 레코드가 표시될 때마다 실행되지만, *Customers* 테이블에 추가된 새로운 항목만 처리합니다. `EmailAddress` 속성이 있는 모든 항목에 대해 Lambda 함수는 Amazon Simple Email Service(Amazon SES)를 호출하여 해당 주소에 이메일을 보냅니다.

![\[신규 고객에게 환영 이메일을 자동으로 전송하기 위한 DynamoDB Streams와 Lambda 통합.\]](http://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/images/HowItWorksStreams.png)


**참고**  
이 예제에서 마지막 고객인 Craig Roe는 `EmailAddress`가 없어 이메일을 받지 못합니다.

트리거뿐만 아니라 DynamoDB Streams는 AWS 리전 내나 리전 간의 데이터 복제, DynamoDB 테이블의 구체화된 데이터 보기, Kinesis 구체화된 보기를 사용한 데이터 분석 등의 강력한 솔루션을 지원합니다.

자세한 내용은 [DynamoDB Streams에 대한 변경 데이터 캡처](Streams.md) 섹션을 참조하세요.

# DynamoDB API
<a name="HowItWorks.API"></a>

Amazon DynamoDB를 사용하려면 애플리케이션에서 몇 가지 간단한 API 작업을 사용해야 합니다. 다음은 이러한 작업을 카테고리별로 정리한 요약본입니다.

**참고**  
전체 API 작업 목록은 [Amazon DynamoDB API 참조](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/Welcome.html)를 참조하세요.

**Topics**
+ [컨트롤 플레인](#HowItWorks.API.ControlPlane)
+ [데이터 영역](#HowItWorks.API.DataPlane)
+ [DynamoDB Streams](#HowItWorks.API.Streams)
+ [트랜잭션](#HowItWorks.API.Transactions)

## 컨트롤 플레인
<a name="HowItWorks.API.ControlPlane"></a>

*제어 영역* 작업을 사용하면 DynamoDB 테이블을 생성하고 관리할 수 있습니다. 또한 인덱스, 스트림 및 테이블에 따라 다른 다양한 객체를 사용하도록 해 줍니다.
+  `CreateTable` - 새 테이블을 생성합니다. 선택 사항으로, 하나 이상의 보조 인덱스를 생성하고 테이블에 DynamoDB Streams를 활성화할 수 있습니다.
+ `DescribeTable` - 기본 키 스키마, 처리량 설정, 인덱스 정보와 같은 테이블에 대한 정보를 반환합니다.
+ `ListTables` - 모든 테이블의 이름을 목록으로 반환합니다.
+ `UpdateTable` - 테이블 또는 해당 인덱스의 설정을 수정하거나, 테이블에서 새 인덱스를 생성 또는 제거하거나, 테이블의 DynamoDB Streams 설정을 수정합니다.
+ `DeleteTable` - DynamoDB에서 테이블 및 해당 종속적 객체 모두를 제거합니다.

## 데이터 영역
<a name="HowItWorks.API.DataPlane"></a>

*데이터 플레인* 작업은 테이블의 데이터에 대해 생성, 읽기, 업데이트 및 삭제(*CRUD*) 작업을 수행하도록 해 줍니다. 또한 일부 데이터 영역 작업을 사용하여 보조 인덱스에서 데이터를 읽을 수 있습니다.

[PartiQL - Amazon DynamoDB용 SQL 호환 쿼리 언어](ql-reference.md)을 사용하여 이러한 CRUD 작업을 수행할 수도 있고 각 작업을 고유한 API 호출로 구분하는 DynamoDB의 클래식 CRUD API를 사용할 수도 있습니다.

### PartiQL - SQL 호환 쿼리 언어
<a name="HowItWorks.API.DataPlane.partiql"></a>
+ `ExecuteStatement` - 테이블에서 여러 항목을 읽습니다. 테이블에서 단일 항목을 쓰거나 업데이트할 수도 있습니다. 단일 항목을 쓰거나 업데이트할 때는 기본 키 속성을 지정해야 합니다.
+ `BatchExecuteStatement` - 테이블에서 여러 항목을 쓰거나, 업데이트하거나, 읽습니다. 항목을 쓰거나 읽을 때 애플리케이션이 네트워크를 한 번만 왕복하면 되므로 `ExecuteStatement`보다 더 효율적입니다.

### 클래식 API
<a name="HowItWorks.API.DataPlane.classic"></a>

#### 데이터 생성
<a name="HowItWorks.API.DataPlane.Create"></a>
+ `PutItem` - 테이블에 단일 항목을 씁니다. 기본 키 속성은 꼭 지정해야 하지만 다른 속성은 지정하지 않아도 됩니다.
+ `BatchWriteItem` - 테이블에 최대 25개의 항목을 씁니다. 항목을 쓸 때 애플리케이션이 네트워크를 한 번만 왕복하면 되므로 `PutItem`을 여러 번 호출하는 것보다 이 작업이 효율적입니다.

#### 데이터 읽기
<a name="HowItWorks.API.DataPlane.Read"></a>
+ `GetItem` - 테이블에서 단일 항목을 가져옵니다. 원하는 항목의 기본 키를 지정해야 합니다. 전체 항목 또는 속성 일부만 가져올 수 있습니다.
+ `BatchGetItem` - 하나 이상의 테이블에서 최대 100개의 항목을 가져옵니다. 항목을 읽을 때 애플리케이션이 네트워크를 한 번만 왕복하면 되므로 `GetItem`을 여러 번 호출하는 것보다 이 작업이 효율적입니다.
+ `Query` - 특정 파티션 키가 있는 모든 항목을 가져옵니다. 파티션 키 값을 지정해야 합니다. 전체 항목 또는 속성 일부만 가져올 수 있습니다. 경우에 따라 정렬 키 값에 조건을 적용하여 파티션 키가 동일한 데이터의 하위 집합만 검색할 수도 있습니다. 테이블에 파티션 키와 정렬 키가 모두 있는 경우 이러한 작업을 테이블에 사용할 수 있습니다. 또한 인덱스에 파티션 키와 정렬 키가 모두 있는 경우 이러한 작업을 인덱스에 사용할 수 있습니다.
+ `Scan` - 지정한 테이블 또는 인덱스의 모든 항목을 가져옵니다. 전체 항목 또는 속성 일부만 가져올 수 있습니다. 선택 사항으로, 필터링 조건을 적용하여 필요한 값만 반환하고 나머지는 버릴 수 있습니다.

#### 데이터 업데이트
<a name="HowItWorks.API.DataPlane.Update"></a>
+ `UpdateItem` - 항목에서 하나 이상의 속성을 수정합니다. 수정하려는 항목의 기본 키를 지정해야 합니다. 새로운 속성을 추가할 수 있으며 기존 속성을 수정하거나 제거할 수 있습니다. 조건부 업데이트를 수행하여 사용자 정의 조건을 만족할 때만 업데이트가 수행되도록 할 수도 있습니다. 선택 사항으로, 원자성 카운터를 구현할 수 있습니다. 이는 다른 쓰기 요청과 충돌하지 않고도 숫자 속성을 증감합니다.

#### 데이터 삭제
<a name="HowItWorks.API.DataPlane.Delete"></a>
+ `DeleteItem` - 테이블에서 단일 항목을 삭제합니다. 삭제하려는 항목의 기본 키를 지정해야 합니다.
+ `BatchWriteItem` - 하나 이상의 테이블에서 최대 25개의 항목을 삭제합니다. 항목을 삭제할 때 애플리케이션이 네트워크를 한 번만 왕복하면 되므로 `DeleteItem`을 여러 번 호출하는 것보다 이 작업이 효율적입니다.
**참고**  
데이터 생성과 삭제에 모두 `BatchWriteItem`을 사용할 수 있습니다.

## DynamoDB Streams
<a name="HowItWorks.API.Streams"></a>

*DynamoDB Streams* 작업을 사용하면 테이블에서 스트림을 활성화하거나 비활성화할 수 있으며, 스트림에 포함되어 있는 데이터 수정 레코드에 액세스할 수 있습니다.
+ `ListStreams` - 모든 스트림 목록 또는 특정 테이블의 스트림만 반환합니다.
+ `DescribeStream` - 해당 Amazon 리소스 이름(ARN) 및 애플리케이션이 처음 몇 개 스트림 레코드를 읽기 시작할 수 있는 위치와 같은 스트림에 대한 정보를 반환합니다.
+ `GetShardIterator` - *샤드 반복자*를 반환합니다. 샤드 반복자는 애플리케이션이 스트림에서 레코드를 가져오는 데 사용하는 데이터 구조입니다.
+ `GetRecords` - 지정된 샤드 반복자를 사용하여 하나 이상의 스트림 레코드를 가져옵니다.

## 트랜잭션
<a name="HowItWorks.API.Transactions"></a>

*트랜잭션*은 원자성, 일관성, 격리 및 내구성(ACID)을 제공하여 애플리케이션에서 데이터의 정확성을 더 쉽게 유지할 수 있습니다.

[PartiQL - Amazon DynamoDB용 SQL 호환 쿼리 언어](ql-reference.md)을 사용하여 트랜잭션 작업을 수행할 수도 있고 각 작업을 고유한 API 호출로 구분하는 DynamoDB의 클래식 CRUD API를 사용할 수도 있습니다.

### PartiQL - SQL 호환 쿼리 언어
<a name="HowItWorks.API.Transactions.DataPlane.partiql"></a>
+ `ExecuteTransaction` - 양자택일 결과가 보장되는 테이블 내와 테이블 간 모두에서 여러 항목에 대한 CRUD 작업을 허용하는 배치 작업입니다.

### 클래식 API
<a name="HowItWorks.API.DataPlane.classic"></a>
+ `TransactWriteItems` - 양자택일 결과가 보장되는 테이블 내와 테이블 간 모두에서 여러 항목에 대한 `Put`, `Update` 및 `Delete` 작업을 허용하는 배치 작업입니다.
+ `TransactGetItems` - 하나 이상의 테이블에서 여러 항목을 가져오는 `Get` 작업을 허용하는 배치 작업입니다.

# Amazon DynamoDB에서 지원되는 데이터 형식 및 이름 지정 규칙
<a name="HowItWorks.NamingRulesDataTypes"></a>

이 섹션에서는 Amazon DynamoDB 이름 지정 규칙 및 DynamoDB가 지원하는 다양한 데이터 형식에 대해 설명합니다. 제한된 데이터 형식이 적용됩니다. 자세한 내용은 [데이터 타입](Constraints.md#limits-data-types) 섹션을 참조하세요.

**Topics**
+ [이름 지정 규칙](#HowItWorks.NamingRules)
+ [데이터 타입](#HowItWorks.DataTypes)
+ [데이터 형식 서술자](#HowItWorks.DataTypeDescriptors)

## 이름 지정 규칙
<a name="HowItWorks.NamingRules"></a>

DynamoDB의 테이블, 속성 및 기타 객체는 이름이 있어야 합니다. 이름은 의미 있고 간결해야 합니다. 예를 들어 *Products*, *Books*, *Authors*와 같이 이름은 쉽게 이해되어야 합니다.

다음은 DynamoDB의 이름 지정 규칙입니다.
+ 모든 이름은 UTF-8로 인코딩되어야 하며, 대소문자를 구분합니다.
+ 테이블 이름 및 인덱스 이름은 3\$1255자로 이루어져야 하며, 다음 문자만 포함할 수 있습니다.
  + `a-z`
  + `A-Z `
  + ` 0-9 `
  + `_` (밑줄)
  + `-`(대시)
  + `.`(점)
+ 속성 이름은 1자 이상이고 크기가 64KB 미만이어야 합니다. 속성 이름을 최대한 짧게 유지하는 것이 좋습니다. 이렇게 하면 속성 이름이 스토리지 및 처리량 사용량 측정에 포함되므로 사용되는 읽기 요청 단위를 줄일 수 있습니다.

  다음과 같은 예외가 있습니다. 이러한 속성 이름은 255자 이내여야 합니다.
  + 보조 인덱스 파티션 키 이름
  + 보조 인덱스 정렬 키 이름
  + 사용자 지정 프로젝션 속성 이름(로컬 보조 인덱스에만 적용 가능) 

### 예약어 및 특수 문자
<a name="HowItWorks.NamingRules.Reserved"></a>

DynamoDB에 예약어 목록과 특수 문자가 있습니다. 전체 목록은 [DynamoDB의 예약어](ReservedWords.md) 섹션을 참조하세요. 또한 DynamoDB에서 **\$1**(해시) 및 **:**(콜론)은 특별한 의미를 갖습니다.

DynamoDB에서 이러한 예약어 및 특수 문자를 이름에 사용하도록 허용하는 경우에도 표현식에서 이러한 이름을 사용할 때마다 자리 표시자 변수를 정의해야 하므로 사용하지 않는 것이 좋습니다. 자세한 내용은 [DynamoDB의 표현식 속성 이름(별칭)](Expressions.ExpressionAttributeNames.md) 섹션을 참조하세요.

## 데이터 타입
<a name="HowItWorks.DataTypes"></a>

DynamoDB는 테이블 내 속성에 대해 다양한 데이터 형식을 지원합니다. 이는 다음과 같이 분류할 수 있습니다.
+ **스칼라 형식** - 스칼라 형식은 하나의 값만 표현할 수 있습니다. 스칼라 형식은 숫자, 문자열, 이진수, 부울 및 Null입니다.
+ **문서 형식** - 문서 형식은 중첩된 속성이 있는 복잡한 구조를 표현할 수 있습니다. 이러한 형식은 JSON 문서에서 찾을 수 있습니다. 문서 형식은 목록 및 맵입니다.
+ **집합 형식** - 집합 형식은 여러 스칼라 값을 표현할 수 있습니다. 집합 형식은 문자열 집합, 숫자 집합 및 이진수 집합입니다.

테이블이나 보조 인덱스를 생성할 때는 각 기본 키 속성(파티션 키 및 정렬 키)의 이름 및 데이터 형식을 지정해야 합니다. 또한, 각 기본 키 속성은 문자열, 숫자 또는 이진수 형식으로 정의해야 합니다.

DynamoDB는 *스키마 없는* NoSQL 데이터베이스입니다. 이는 테이블을 생성할 때 프라이머리 키 속성 외에는 다른 속성이나 데이터 형식을 정의할 필요가 없다는 의미입니다. 그에 비해, 관계형 데이터베이스는 테이블을 생성할 때 각 열의 이름 및 데이터 형식을 정의해야 합니다.

다음은 각 데이터 형식을 JSON 형식의 예제와 함께 설명한 것입니다.

### 스칼라 형식
<a name="HowItWorks.DataTypes.Scalar"></a>

스칼라 형식은 숫자, 문자열, 이진수, 부울 및 Null입니다.

#### 숫자
<a name="HowItWorks.DataTypes.Number"></a>

번호는 양수, 음수 또는 0일 수 있습니다. 숫자는 최대 38자릿수까지 지원됩니다. 이 제한을 초과하면 예외가 발생합니다. 소수점 아래 38자리보다 높은 정밀도가 필요한 경우 문자열을 사용할 수 있습니다.
+ 양의 범위: 1E-130 \$1 9.9999999999999999999999999999999999999E\$1125
+ 음의 범위: -9.9999999999999999999999999999999999999E\$1125 \$1 -1E-130

DynamoDB에서 숫자는 가변 길이로 나타냅니다. 앞과 끝의 0은 잘립니다.

모든 숫자는 언어와 라이브러리 간의 호환성을 극대화하기 위해 네트워크를 통해 DynamoDB에 문자열로 전송됩니다. 하지만 DynamoDB는 해당 문자열을 연산 작업에서 숫자 형식 속성으로 처리합니다.

번호 데이터 형식을 사용하면 날짜 또는 타임스탬프를 표현할 수 있습니다. 이렇게 하는 한 가지 방법은 1970년 1월 1일 00:00:00 UTC 이후 경과된 시간(초)인 epoch 시간을 사용하는 것입니다. 예를 들어, epoch 시간 `1437136300`은 2015년 7월 17일 오후 12:31:40 UTC를 나타냅니다.

자세한 내용은 [http://en.wikipedia.org/wiki/Unix\$1time](http://en.wikipedia.org/wiki/Unix_time)을 참조하세요.

#### 문자열
<a name="HowItWorks.DataTypes.String"></a>

문자열은 UTF-8 이진수 인코딩을 사용하는 유니코드입니다. 속성이 인덱스 또는 테이블의 키로 사용되지 않고 최대 DynamoDB 항목 크기 제한인 400KB로 제한되는 경우 문자열의 최소 길이는 0일 수 있습니다.

문자열 형식으로 정의된 기본 키 속성에는 다음과 같은 제약이 추가로 적용됩니다.
+ 단순 기본 키의 경우 첫 번째 속성 값(파티션 키)의 최대 길이는 2048바이트입니다.
+ 복합 기본 키의 경우 두 번째 속성 값(정렬 키)의 최대 길이는 1024바이트입니다.

DynamoDB는 기본 UTF-8 문자열 인코딩의 바이트를 사용하여 문자열을 수집하고 비교합니다. 예를 들어 "`a`" (0x61)"은 "`A`" (0x41)보다 크고, "`¿`" (0xC2BF)는 "`z`" (0x7A)보다 큽니다.

문자열 데이터 형식을 사용하면 날짜 또는 타임스탬프를 표현할 수 있습니다. 다음 예에서와 같이 ISO 8601 문자열을 사용하여 이러한 작업이 가능합니다.
+ `2016-02-15`
+ `2015-12-21T17:42:34Z`
+ `20150311T122706Z`

자세한 내용은 [http://en.wikipedia.org/wiki/ISO\$18601](http://en.wikipedia.org/wiki/ISO_8601)을 참조하세요.

**참고**  
기존 관계형 데이터베이스와 달리 DynamoDB는 기본적으로 날짜 및 시간 데이터 유형을 지원하지 않습니다. 대신 Unix epoch 시간을 사용하여 날짜 및 시간 데이터를 숫자 데이터 유형으로 저장하는 것이 유용할 수 있습니다.

#### 바이너리
<a name="HowItWorks.DataTypes.Binary"></a>

이진수 형식의 속성에는 압축 텍스트, 암호화 데이터 또는 이미지 같은 모든 이진수 데이터가 저장될 수 있습니다. DynamoDB는 이진수 값을 비교할 때마다 이진수 데이터의 각 바이트를 부호가 없는 것으로 처리합니다.

속성이 인덱스 또는 테이블의 키로 사용되지 않고 최대 DynamoDB 항목 크기 제한인 400KB로 제한되는 경우 이진 속성의 길이는 0일 수 있습니다.

이진수 형식 속성으로 기본 키 속성을 정의하는 경우 다음 추가 제약이 적용됩니다.
+ 단순 기본 키의 경우 첫 번째 속성 값(파티션 키)의 최대 길이는 2048바이트입니다.
+ 복합 기본 키의 경우 두 번째 속성 값(정렬 키)의 최대 길이는 1024바이트입니다.

애플리케이션에서는 데이터를 DynamoDB로 보내기 전에 Base64 인코딩 형식으로 이진수 값을 인코딩해야 합니다. DynamoDB가 이러한 값을 받아 데이터를 부호가 없는 바이트 배열로 디코딩하고 이진수 속성 길이로 사용합니다.

다음은 base64 인코딩 텍스트를 사용하여 이진수 속성을 나타낸 예제입니다.

```
dGhpcyB0ZXh0IGlzIGJhc2U2NC1lbmNvZGVk
```

#### 부울
<a name="HowItWorks.DataTypes.Boolean"></a>

부울 형식의 속성은 `true` 또는 `false`를 저장할 수 있습니다.

#### Null
<a name="HowItWorks.DataTypes.Null"></a>

Null은 알려지지 않았거나 정의되지 않은 상태의 속성을 나타냅니다.

### 문서 형식
<a name="HowItWorks.DataTypes.Document"></a>

문서 형식은 목록 및 맵입니다. 이러한 데이터 형식은 서로 중첩이 가능하여 최대 32개 깊이 수준의 복잡한 데이터 구조까지 나타낼 수 있습니다.

목록 또는 맵 내 값의 수에는 제한이 없습니다. 단, 값을 포함하는 항목이 DynamoDB 항목 크기 제한(400KB)을 초과하지 않아야 합니다.

 속성이 테이블 또는 인덱스 키에 사용되지 않는 경우 속성 값은 빈 문자열이거나 빈 이진 값일 수 있습니다. 속성 값은 빈 집합(문자열 집합, 숫자 집합 또는 이진 집합)일 수 없지만 빈 목록 및 맵은 허용됩니다. 목록과 맵 내에서는 빈 문자열과 이진 값이 허용됩니다. 자세한 내용은 [속성](Constraints.md#limits-attributes) 섹션을 참조하세요.

#### List
<a name="HowItWorks.DataTypes.Document.List"></a>

목록 형식 속성은 순서가 지정된 값 모음을 저장할 수 있습니다. 목록은 대괄호(`[ ... ]`)로 묶습니다.

목록은 JSON 배열과 유사합니다. 목록 요소에 저장할 수 있는 데이터 형식에는 제한이 없으며, 한 목록 요소에 있는 요소의 형식이 달라도 상관없습니다.

다음은 두 개의 문자열과 하나의 숫자를 포함하는 목록 예제입니다.

```
FavoriteThings: ["Cookies", "Coffee", 3.14159]
```

**참고**  
DynamoDB는 각 요소가 깊게 중첩되었다고 해도 목록 내의 개별 요소를 사용할 수 있습니다. 자세한 내용은 [DynamoDB에서 표현식 사용](Expressions.md) 섹션을 참조하세요.

#### 맵
<a name="HowItWorks.DataTypes.Document.Map"></a>

맵 형식 속성은 정렬되지 않은 이름-값 페어의 모음을 저장할 수 있습니다. 맵은 중괄호(`{ ... }`)로 묶습니다.

맵은 JSON 객체와 유사합니다. 맵 요소에 저장할 수 있는 데이터 형식에는 제한이 없으며, 한 맵에 형식이 다른 요소도 함께 있을 수 있습니다.

맵은 DynamoDB에 JSON 문서를 저장하는 데 이상적입니다. 다음은 문자열, 숫자 및 다른 맵을 포함하는 중첩 목록이 저장된 맵을 나타내는 예제입니다.

```
{
    Day: "Monday",
    UnreadEmails: 42,
    ItemsOnMyDesk: [
        "Coffee Cup",
        "Telephone",
        {
            Pens: { Quantity : 3},
            Pencils: { Quantity : 2},
            Erasers: { Quantity : 1}
        }
    ]
}
```

**참고**  
DynamoDB는 각 요소가 깊게 중첩되었다고 해도 맵 내의 개별 요소를 사용할 수 있습니다. 자세한 내용은 [DynamoDB에서 표현식 사용](Expressions.md) 섹션을 참조하세요.

### 집합
<a name="HowItWorks.DataTypes.SetTypes"></a>

DynamoDB에서도 숫자, 문자열 또는 이진수 값의 집합을 나타내는 형식을 지원합니다. 집합 내의 모든 요소의 형식은 동일해야 합니다. 예를 들어, 숫자 집합은 숫자만 포함할 수 있으며, 문자열 집합은 문자열만 포함할 수 있는 식입니다.

집합 내 값의 수에는 제한이 없습니다. 단, 값을 포함하는 항목이 DynamoDB 항목 크기 제한(400KB)을 초과하지 않아야 합니다.

집합 내의 각 값은 고유해야 합니다. 집합 내 값의 순서는 유지되지 않습니다. 따라서 애플리케이션이 집합 내에서 요소가 특정 순서로 유지된다는 가정 하에 실행되지 않아야 합니다. DynamoDB는 빈 집합을 지원하지 않지만 집합 내에서 빈 문자열과 이진 값이 허용됩니다.

다음은 하나의 문자열 집합, 하나의 숫자 집합과 이진 집합이 포함된 예제입니다.

```
["Black", "Green", "Red"]

[42.2, -19, 7.5, 3.14]

["U3Vubnk=", "UmFpbnk=", "U25vd3k="]
```

## 데이터 형식 서술자
<a name="HowItWorks.DataTypeDescriptors"></a>

하위 수준 DynamoDB API 프로토콜은 *데이터 형식 서술자*를 DynamoDB에 각 속성을 해석하는 방법을 알려 주는 토큰으로 사용합니다.

다음은 DynamoDB 데이터 형식 서술자의 전체 목록입니다.
+ **`S`** - 문자열
+ **`N`** - 숫자
+ **`B`** - 이진수
+ **`BOOL`** - 부울
+ **`NULL`** - Null
+ **`M`** - 맵
+ **`L`** - 목록
+ **`SS`** - 문자열 집합
+ **`NS`** - 숫자 집합
+ **`BS`** - 이진수 집합

# DynamoDB 테이블 클래스
<a name="HowItWorks.TableClasses"></a>

DynamoDB는 비용을 최적화할 수 있도록 설계된 두 가지 테이블 클래스를 제공합니다. DynamoDB Standard 테이블 클래스가 기본값이며 대다수의 워크로드에 권장됩니다. DynamoDB Standard-Infrequent Access(DynamoDB Standard-IA) 테이블 클래스는 스토리지 비용이 많이 드는 테이블에 최적화되어 있습니다. 예를 들어 애플리케이션 로그, 이전 소셜 미디어 게시물, 전자 상거래 주문 내역 및 과거 게임 성과 같이 자주 액세스하지 않는 데이터를 저장하는 테이블은 Standard-IA 테이블 클래스에 적합합니다. 요금 세부 정보는 [Amazon DynamoDB 요금](https://aws.amazon.com/dynamodb/pricing/on-demand/)을 참조하세요.

모든 DynamoDB 테이블은 테이블 클래스(기본적으로 DynamoDB Standard)와 연결됩니다. 테이블과 연결된 모든 보조 인덱스는 동일한 테이블 클래스를 사용합니다. 각 테이블 클래스는 데이터 스토리지와 읽기 및 쓰기 요청에 대해 서로 다른 요금이 적용됩니다. 스토리지 및 처리량 사용 패턴에 따라 테이블에 가장 비용 효율적인 테이블 클래스를 선택할 수 있습니다.

테이블 클래스의 선택은 영구적이지 않습니다.AWS Management Console, AWS CLI, 또는 AWS SDK를 사용하여 이 설정을 변경할 수 있습니다. DynamoDB는 또한 단일 리전 테이블 및 글로벌 테이블에 대해 AWS CloudFormation을 사용하여 테이블 클래스를 관리하는 것을 지원합니다. 테이블 클래스 선택에 대한 자세한 내용은 [DynamoDB에서 테이블 클래스 선택 시 고려 사항](WorkingWithTables.tableclasses.md) 섹션을 참조하세요.

# DynamoDB의 파티션 및 데이터 배포
<a name="HowItWorks.Partitions"></a>

Amazon DynamoDB는 데이터를 파티션에 저장합니다. *파티션*은 SSD(Solid State Drive)로 백업되는 테이블용 스토리지 할당으로, AWS 리전 내의 여러 가용 영역에 자동으로 복제됩니다. 파티션 관리는 DynamoDB에서 전적으로 처리하므로 사용자가 파티션을 직접 관리할 필요가 없습니다.

테이블을 생성할 때 테이블 초기 상태는 `CREATING`입니다. 이 단계 동안, DynamoDB는 테이블에 충분한 파티션을 할당하여 프로비저닝된 처리량 요구 사항을 만족할 수 있도록 합니다. 테이블 상태가 `ACTIVE`로 전환되면 테이블 데이터를 쓰거나 읽을 수 있습니다.

DynamoDB는 다음과 같은 상황에서 테이블에 추가 파티션을 할당합니다.
+ 기존 파티션이 지원할 수 있는 한도를 초과하여 테이블의 할당된 처리량 설정을 늘리는 경우.
+ 기존 파티션 용량이 다 차서 추가 스토리지 공간이 필요한 경우.

파티션 관리는 백그라운드에서 자동으로 이루어지므로 애플리케이션에는 표시되지 않습니다. 테이블은 사용 가능한 처리량을 유지하며 프로비저닝된 처리량 요구 사항을 완전히 지원합니다.

자세한 내용은 [파티션 키 설계](bp-partition-key-design.md) 섹션을 참조하세요.

DynamoDB의 글로벌 보조 인덱스도 파티션으로 구성됩니다. 글로벌 보조 인덱스의 데이터는 기본 테이블의 데이터와 별도로 저장되지만 인덱스 파티션은 테이블 파티션과 동일한 방식으로 동작합니다.

## 데이터 배포: 파티션 키
<a name="HowItWorks.Partitions.SimpleKey"></a>

테이블이 단순 기본 키를 가질 경우(파티션 키만 있음) DynamoDB가 파티션 키 값을 기준으로 각 항목을 저장하고 검색합니다.

테이블에 항목을 쓰기 위해 DynamoDB는 내부 해시 함수에 대한 입력으로 파티션 키 값을 사용합니다. 해시 함수 출력 값은 항목을 저장할 파티션을 결정합니다.

테이블에서 항목을 읽으려면 항목의 파티션 키 값을 지정해야 합니다. DynamoDB는 이 값을 해당 해시 함수의 입력으로 사용하여 항목을 찾을 수 있는 파티션을 결정합니다.

다음 다이어그램은 여러 파티션에 걸쳐 데이터가 저장된 *Pets*라는 테이블을 보여줍니다. 테이블의 기본 키는*AnimalType*입니다(이 키 속성만 표시됨). DynamoDB는 해시 함수를 사용하여 새 항목을 저장할 위치를 결정합니다. 이 경우 문자열 *Dog*의 해시 값이 기준으로 사용됩니다. 항목은 정렬 순서대로 저장되지 않습니다. 각 항목의 위치는 파티션 키의 해시 값으로 결정됩니다.

![\[파티션 키 해시 값에 기반한 DynamoDB의 파티션 간 테이블 항목 배포.\]](http://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/images/HowItWorksPartitionKey.png)


**참고**  
DynamoDB는 파티션 수와 상관없이 항목을 테이블의 파티션에 균일하게 분배하는 데 최적화되어 있습니다. 테이블 항목 수에 비해 많은 수의 고유 값을 가질 수 있는 파티션 키를 선택할 것을 권장합니다.

## 데이터 배포: 파티션 키 및 정렬 키
<a name="HowItWorks.Partitions.CompositeKey"></a>

테이블에 복합 기본 키(파티션 키 및 정렬 키)가 있는 경우 [데이터 배포: 파티션 키](#HowItWorks.Partitions.SimpleKey)에 설명된 동일한 방식으로 DynamoDB에서 파티션 키의 해시 값을 계산합니다. 하지만 파티션 키 값이 같은 항목을 서로 가깝게 유지하고 정렬 키 속성 값을 기준으로 정렬하는 경향이 있습니다. 동일한 파티션 키 속성 값을 가진 항목 세트를 항목 모음이라고 합니다. 항목 모음은 모음 내 항목 범위를 효율적으로 검색할 수 있도록 최적화되어 있습니다. 테이블에 로컬 보조 인덱스가 없는 경우 DynamoDB는 데이터를 저장하고 읽기 및 쓰기 처리량을 제공하는 데 필요한 만큼의 파티션으로 항목 모음을 자동으로 분할합니다.

테이블에 항목을 기록하기 위해 DynamoDB는 파티션 키의 해시 값을 계산하여 항목을 저장할 파티션을 결정합니다. 해당 파티션에서는 여러 항목이 동일한 파티션 키 값을 가질 수 있습니다. 따라서 DynamoDB에서 동일한 파티션 키의 다른 항목 간에 정렬 키에 의해 오름차순으로 항목을 저장합니다.

테이블에서 항목을 읽으려면 항목의 파티션 키 값과 정렬 키 값을 지정해야 합니다. DynamoDB는 파티션 키의 해시 값을 계산하여 항목을 찾을 수 있는 파티션을 결정합니다.

원하는 항목이 동일한 파티션 키 값을 가질 경우 단일 작업(`Query`)으로 테이블에서 여러 항목을 읽을 수 있습니다. DynamoDB는 해당 파티션 키 값을 갖는 모든 항목을 반환합니다. 특정 값 범위의 항목만 반환되도록 정렬 키에 조건을 적용할 수 있습니다(선택 사항).

*Pets* 테이블이 *AnimalType*(파티션 키)와 *Name*(정렬 키)으로 구성된 복합 기본 키를 가진다고 가정하겠습니다. 다음 다이어그램에서는 DynamoDB가 파티션 키 값 *Dog*와 정렬 키 값 *Fido*를 사용하여 항목을 씁니다.

![\[DynamoDB는 복합 파티션 키가 있는 항목을 저장하고 정렬 키 속성 값을 사용하여 항목을 정렬합니다.\]](http://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/images/HowItWorksPartitionKeySortKey.png)


*Pets* 테이블에서 동일한 항목을 읽기 위해 DynamoDB는 *Dog*의 해시 값을 계산하여 이들 항목이 저장된 파티션을 알아냅니다. 그런 다음 DynamoDB는 *Fido*를 찾을 때까지 정렬 키 속성 값을 스캔합니다.

*AnimalType*이 *Dog*인 항목을 모두 읽으려면 정렬 키 조건을 지정하지 않고 `Query` 작업을 실행합니다. 기본적으로 항목은 정렬 순서대로, 즉 정렬 키 기준 오름차순으로 반환됩니다. 선택 사항으로 내림차순을 요청할 수 있습니다.

일부 *Dog* 항목만 쿼리하려면 정렬 키에 조건을 적용할 수 있습니다(예: *Name*이 `A`\$1`K` 범위 내 문자로 시작하는 *Dog* 항목만).

**참고**  
DynamoDB 테이블에서 파티션 키 값당 고유 정렬 키 값의 수는 상한이 없습니다. *Pets* 테이블에서 수십억 개의 *Dog* 항목을 저장해야 하는 경우 DynamoDB는 충분한 스토리지를 할당하여 이 요구 사항을 자동으로 처리합니다.

# SQL에서 NoSQL로 전환하는 방법 알아보기
<a name="SQLtoNoSQL"></a>

애플리케이션 개발자라면 RDBMS(관계형 데이터베이스 관리 시스템) 및 SQL(Structured Query Language)을 사용한 경험이 어느 정도 있을 것입니다. Amazon DynamoDB 작업을 시작해 보면 비슷한 점도 많겠지만 다른 점도 상당히 많습니다. *NoSQL*은 가용성과 확장성이 높고 고성능에 최적화된 비관계형 데이터베이스 시스템을 설명하는 데 사용되는 용어입니다. NoSQL 데이터베이스(예: DynamoDB)는 관계형 모델 대신 키 값 페어나 문서 스토리지 같은 대체 모델을 데이터 관리에 사용합니다. 자세한 내용은 [NoSQL이란 무엇입니까?](https://aws.amazon.com/nosql)를 참조하세요.

Amazon DynamoDB는 오픈 소스 SQL 호환 쿼리 언어인 [PartiQL](https://partiql.org/)을 지원합니다. 이 언어를 사용하면 데이터가 저장되는 위치 또는 형식과 관계없이 데이터를 효율적으로 쿼리할 수 있습니다. PartiQL을 사용하면 관계형 데이터베이스의 구조화된 데이터, 개방형 데이터 형식의 반정형 및 중첩 데이터, 행에 따라 다른 속성을 지정할 수 있는 NoSQL 또는 문서 데이터베이스의 스키마 없는 데이터까지도 손쉽게 처리할 수 있습니다. 자세한 내용은 [PartiQL 쿼리 언어](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)를 참조하세요.

다음 섹션에서는 SQL 문을 그에 상당하는 DynamoDB 작업과 비교 대조하면서 공통 데이터베이스 작업에 대해 설명합니다.

**참고**  
이 섹션의 SQL 예제는 MySQL RDBMS와 호환됩니다.  
이 섹션의 DynamoDB 예제는 DynamoDB 작업의 이름과 함께 JSON 형식의 해당 작업 파라미터를 보여 줍니다.

**Topics**
+ [관계형(SQL)과 NoSQL 중에서 선택](SQLtoNoSQL.WhyDynamoDB.md)
+ [관계형(SQL) 데이터베이스 및 DynamoDB 액세스 비교](SQLtoNoSQL.Accessing.md)
+ [테이블 생성 시 관계형(SQL) 데이터베이스 및 DynamoDB 비교](SQLtoNoSQL.CreateTable.md)
+ [관계형(SQL) 데이터베이스 및 DynamoDB에서 테이블 정보 가져오기 비교](SQLtoNoSQL.GetTableInfo.md)
+ [테이블에 데이터를 쓸 때의 관계형(SQL) 데이터베이스와 DynamoDB 비교](SQLtoNoSQL.WriteData.md)
+ [테이블에서 데이터를 읽을 때의 관계형(SQL) 데이터베이스와 DynamoDB 비교](SQLtoNoSQL.ReadData.md)
+ [인덱스 관리 시 관계형(SQL) 데이터베이스와 DynamoDB 비교](SQLtoNoSQL.Indexes.md)
+ [테이블에서 데이터를 수정할 때 관계형(SQL) 데이터베이스와 DynamoDB 비교](SQLtoNoSQL.UpdateData.md)
+ [테이블에서 데이터를 삭제할 때 관계형(SQL) 데이터베이스와 DynamoDB 비교](SQLtoNoSQL.DeleteData.md)
+ [테이블 제거 시 관계형(SQL) 데이터베이스와 DynamoDB 비교](SQLtoNoSQL.RemoveTable.md)

# 관계형(SQL)과 NoSQL 중에서 선택
<a name="SQLtoNoSQL.WhyDynamoDB"></a>

오늘날의 애플리케이션의 요구 사항은 그 어느 때보다 까다롭습니다. 예를 들어 온라인 게임은 소수의 사용자와 아주 작은 양의 데이터만으로 시작될 수 있습니다. 하지만 게임이 성공을 거두면 기본 데이터베이스 시스템의 리소스를 가볍게 초과할 수 있습니다. 웹 기반 애플리케이션의 동시 사용자가 수백 명, 수천 명 또는 수백만 명에 이르고, 매일 테라바이트 규모의 데이터가 새로 생성되는 경우는 드물지 않습니다. 이런 애플리케이션의 데이터베이스는 초당 수만(혹은 수십만) 건의 읽기 및 쓰기를 처리해야 합니다.

Amazon DynamoDB는 이런 종류의 워크로드에 적합합니다. 개발자는 작은 크기로 시작하고, 애플리케이션의 인기가 높아짐에 따라 사용률을 점차로 늘릴 수 있습니다. DynamoDB는 대량의 데이터와 매우 많은 수의 사용자를 처리할 수 있도록 크기를 원활하게 조정합니다.

기존 관계형 데이터베이스 모델링과 이를 DynamoDB에 맞게 조정하는 방법에 대한 자세한 내용은 [DynamoDB의 관계형 데이터 모델링 모범 사례](bp-relational-modeling.md) 섹션을 참조하세요.

다음 표에서는 관계형 데이터베이스 관리 시스템(RDBMS)과 DynamoDB의 몇 가지 중요한 차이점을 보여줍니다.


****  

| 기능 | 관계형 데이터베이스 관리 시스템(RDBMS) | Amazon DynamoDB | 
| --- | --- | --- | 
| 최적의 워크로드 | 임시 쿼리, 데이터 웨어하우징, OLAP(Online Analytical Processing). | 소셜 네트워크, 게이밍, 미디어 공유, IoT(사물 인터넷) 등 웹 규모의 애플리케이션입니다. | 
| 데이터 모델 | 관계형 모델의 경우 데이터가 테이블, 행 및 열로 정규화되는 잘 정의된 스키마가 필요합니다. 뿐만 아니라 테이블, 행, 인덱스 및 기타 데이터베이스 간의 모든 관계가 정의됩니다. | DynamoDB는 스키마가 없습니다. 각 테이블에는 각각의 데이터 항목을 고유하게 식별하는 기본 키가 있어야 하지만 키가 아닌 다른 속성에는 비슷한 제한이 없습니다. DynamoDB는 JSON 문서를 비롯한 정형 또는 반정형 데이터를 관리할 수 있습니다. | 
| 데이터 액세스 | SQL은 데이터 저장과 검색을 위한 표준입니다. 관계형 데이터베이스는 데이터베이스 중심 애플리케이션 개발을 단순화하는 풍부한 도구 세트를 제공하지만 이 도구 모두가 SQL을 사용하는 것은 아닙니다. | AWS Management Console, AWS CLI 또는 NoSQL WorkBench를 사용하여 DynamoDB 작업을 수행하고 임시 태스크를 수행할 수 있습니다. SQL 호환 쿼리 언어인 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)을 사용하여 DynamoDB에서 데이터를 선택, 삽입, 업데이트, 삭제할 수 있습니다. 애플리케이션은 AWS 소프트웨어 개발 키트(SDK)를 활용하여 객체 기반, 문서 중심 또는 하위 수준 인터페이스를 통해 DynamoDB 작업을 할 수 있습니다. | 
| 성능: | 관계형 데이터베이스는 스토리지에 최적화되어 있으므로 일반적으로 성능은 디스크 하위 시스템에 좌우됩니다. 개발자와 데이터베이스 관리자는 성능 극대화를 위해 쿼리, 인덱스 및 테이블 구조를 최적화해야 합니다. | DynamoDB는 컴퓨팅에 최적화되어 있기 때문에 성능은 주로 기본 하드웨어와 네트워크 대기 시간에 달려 있습니다. 관리형 서비스인 DynamoDB는 사용자와 사용자 애플리케이션이 이런 구현 세부 사항에 영향을 받지 않도록 보호하여 견고한 고성능 애플리케이션을 설계하고 구축하는 데 집중할 수 있게 합니다. | 
| 규모 조정 | 보다 빠른 하드웨어를 통한 확장은 더할 나위 없이 쉽습니다. 데이터베이스 테이블을 분산 시스템의 여러 호스트에 배치하는 것도 가능하지만 여기에는 추가 투자가 필요합니다. 관계형 데이터베이스는 파일 숫자와 크기에 최대치가 있어 이것이 확장성의 상한선이 됩니다. | DynamoDB는 분산된 하드웨어 클러스터를 사용하여 확장하도록 설계되었습니다. 이런 설계 덕에 지연 시간 증가 없는 처리 능력 증대가 가능합니다. 고객이 처리량 요구 사항을 지정하면 DynamoDB는 충분한 리소스를 할당하여 이 요구 사항을 충족합니다. 테이블당 항목 수에 상한선이 없고, 테이블의 총 크기 역시 마찬가지입니다. | 

# 관계형(SQL) 데이터베이스 및 DynamoDB 액세스 비교
<a name="SQLtoNoSQL.Accessing"></a>

애플리케이션에서 데이터베이스에 액세스할 수 있으려면 애플리케이션에서 해당 데이터베이스를 사용할 수 있도록 애플리케이션이 *인증*되어야 합니다. 애플리케이션은 해당 권한을 가진 작업만 수행할 수 있도록 *권한 부여*되어야 합니다.

다음 다이어그램은 관계형 데이터베이스 및 Amazon DynamoDB와의 클라이언트 상호 작용을 보여줍니다.

![\[관계형 및 NoSQL 데이터베이스와의 상호 작용\]](http://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/images/SQLtoNoSQL.png)


다음 표에는 클라이언트 상호 작용 작업에 대한 자세한 내용이 나와 있습니다.


****  

| 기능 | 관계형 데이터베이스 관리 시스템(RDBMS) | Amazon DynamoDB | 
| --- | --- | --- | 
| 데이터베이스 액세스 도구 |  대부분의 관계형 데이터베이스는 명령줄 인터페이스(CLI)를 제공하므로 특별 SQL 문을 입력하고 결과를 즉시 확인할 수 있습니다.  | 대부분의 경우에는 애플리케이션 코드를 작성합니다. AWS Management Console, AWS Command Line Interface(AWS CLI) 또는 NoSQL Workbench를 사용하여 DynamoDB에 임시 요청을 보내고 결과를 볼 수도 있습니다. SQL 호환 쿼리 언어인 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)을 사용하여 DynamoDB에서 데이터를 선택, 삽입, 업데이트, 삭제할 수 있습니다. | 
| 데이터베이스에 연결 | 애플리케이션은 데이터베이스와의 네트워크 연결을 구축하고 유지합니다. 애플리케이션은 종료될 때 연결을 끊습니다. | DynamoDB는 웹 서비스이며, 해당 데이터베이스와 상호 작용은 상태 비저장입니다. 애플리케이션은 지속적인 네트워크 연결을 유지할 필요가 없습니다. 그 대신 DynamoDB와의 상호 작용은 HTTP(S) 요청 및 응답을 사용하여 이루어집니다. | 
| Authentication | 애플리케이션은 인증되기 전에는 데이터베이스에 연결할 수 없습니다. RDBMS는 직접 인증을 수행하거나 호스트 운영 체제 또는 디렉터리 서비스에 이 작업을 오프로드할 수 있습니다. | DynamoDB에 대한 모든 요청에는 해당 특정 요청을 인증하는 암호화 서명이 함께 제공되어야 합니다. AWS SDK는 서명 및 서명 요청을 생성하는 데 필요한 모든 로직을 제공합니다. 자세한 내용은 AWS 일반 참조의 [AWS API 요청 서명](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)을 참조하세요. | 
| 권한 부여 | 애플리케이션은 권한을 부여받은 작업만 수행할 수 있습니다. 데이터베이스 관리자나 애플리케이션 소유자는 SQL GRANT 및 REVOKE 문을 사용하여 (테이블 등의) 데이터베이스 객체, (테이블 내의 행 등의) 데이터 또는 특정 SQL 문 발행 능력에 대한 액세스를 제어할 수 있습니다. | DynamoDB에서는 AWS Identity and Access Management(IAM)에 의해 권한 부여가 처리됩니다. 테이블과 같은 DynamoDB 리소스에 대한 권한을 부여하는 IAM 정책을 작성한 다음 사용자 및 역할이 해당 정책을 사용하도록 허용할 수 있습니다. IAM은 DynamoDB 테이블의 개별 항목에 대한 액세스를 세부적으로 제어할 수도 있습니다. 자세한 내용은 [Amazon DynamoDB의 Identity and Access Management](security-iam.md) 섹션을 참조하세요. | 
| 요청 전송 | 애플리케이션은 수행하려는 모든 데이터베이스 작업에 대해 SQL 문을 발행합니다. SQL 문을 수신하면 RDBMS는 구문을 확인하고 작업 수행 계획을 생성한 다음 계획을 실행합니다. | 애플리케이션은 HTTP(S) 요청을 DynamoDB에 보냅니다. 요청에는 수행할 DynamoDB 작업의 이름과 함께 파라미터가 포함되어 있습니다. DynamoDB는 요청을 즉시 실행합니다. | 
| 응답 수신 | RDBMS는 SQL 문의 결과를 반환합니다. 오류가 있는 경우, RDBMS는 오류 상태와 메시지를 반환합니다. | DynamoDB는 작업 결과가 포함된 HTTP(S) 응답을 반환합니다. 오류가 있는 경우 DynamoDB는 HTTP 오류 상태 및 메시지를 반환합니다. | 

# 테이블 생성 시 관계형(SQL) 데이터베이스 및 DynamoDB 비교
<a name="SQLtoNoSQL.CreateTable"></a>

테이블은 관계형 데이터베이스와 Amazon DynamoDB의 기본 데이터 구조입니다. 관계형 데이터베이스 관리 시스템(RDBMS)에서는 테이블을 생성할 때 테이블의 스키마를 정의해야 합니다. 반면 DynamoDB 테이블은 스키마가 없습니다. 즉, 테이블을 생성할 때 기본 키 외에는 추가 속성이나 데이터 형식을 정의할 필요가 없습니다.

다음 섹션에서는 SQL을 사용하여 테이블을 생성하는 방법과 DynamoDB를 사용하여 테이블을 생성하는 방법을 비교합니다.

**Topics**
+ [SQL에서 테이블 생성](#SQLtoNoSQL.CreateTable.SQL)
+ [DynamoDB에서 테이블 생성](#SQLtoNoSQL.CreateTable.DynamoDB)

## SQL에서 테이블 생성
<a name="SQLtoNoSQL.CreateTable.SQL"></a>

SQL에서는 다음 예에 나온 것처럼 `CREATE TABLE` 문을 사용하여 테이블을 생성합니다.

```
CREATE TABLE Music (
    Artist VARCHAR(20) NOT NULL,
    SongTitle VARCHAR(30) NOT NULL,
    AlbumTitle VARCHAR(25),
    Year INT,
    Price FLOAT,
    Genre VARCHAR(10),
    Tags TEXT,
    PRIMARY KEY(Artist, SongTitle)
);
```

이 테이블의 기본 키는 *Artist* 및 *SongTitle*로 구성됩니다.

테이블의 모든 열과 데이터 형식 및 테이블의 기본 키를 정의해야 합니다. (필요할 경우, `ALTER TABLE` 문을 사용하여 나중에 이 정의를 변경할 수 있습니다.)

많은 SQL 구현에서는 `CREATE TABLE` 문의 일부로 테이블의 스토리지 사양을 정의할 수 있습니다. 달리 지정하지 않는 한 테이블은 기본 스토리지 설정으로 생성됩니다. 프로덕션 환경에서 데이터베이스 관리자는 최적의 스토리지 파라미터 결정을 도울 수 있습니다.

## DynamoDB에서 테이블 생성
<a name="SQLtoNoSQL.CreateTable.DynamoDB"></a>

다음 예에 나온 것처럼 `CreateTable` 작업을 사용하여 프로비저닝된 모드 테이블을 생성하고 파라미터를 지정합니다.

```
{
    TableName : "Music",
    KeySchema: [
        {
            AttributeName: "Artist",
            KeyType: "HASH" //Partition key
        },
        {
            AttributeName: "SongTitle",
            KeyType: "RANGE" //Sort key
        }
    ],
    AttributeDefinitions: [
        {
            AttributeName: "Artist",
            AttributeType: "S"
        },
        {
            AttributeName: "SongTitle",
            AttributeType: "S"
        }
    ],
    ProvisionedThroughput: {       // Only specified if using provisioned mode
        ReadCapacityUnits: 1,
        WriteCapacityUnits: 1
    }
}
```

이 테이블의 기본 키는 *Artist*(파티션 키)와 *SongTitle*(정렬 키)로 구성됩니다.

다음 파라미터를 `CreateTable`에 입력해야 합니다.
+ `TableName` - 테이블 이름
+ `KeySchema` - 기본 키에 사용되는 속성. 자세한 내용은 [테이블, 항목 및 속성](HowItWorks.CoreComponents.md#HowItWorks.CoreComponents.TablesItemsAttributes) 및 [프라이머리 키](HowItWorks.CoreComponents.md#HowItWorks.CoreComponents.PrimaryKey) 섹션을 참조하세요.
+ `AttributeDefinitions` - 키 스키마 속성의 데이터 형식
+ `ProvisionedThroughput (for provisioned tables)` - 이 테이블에 필요한 초당 읽기 및 쓰기 수. DynamoDB는 처리량 요구 사항이 항상 충족되도록 충분한 스토리지 및 시스템 리소스를 남겨 둡니다. 필요할 경우, `UpdateTable` 작업을 사용하여 나중에 이를 변경할 수 있습니다. 스토리지 할당이 전적으로 DynamoDB에 의해 관리되기 때문에 테이블의 스토리지 요구 사항을 지정할 필요가 없습니다.

# 관계형(SQL) 데이터베이스 및 DynamoDB에서 테이블 정보 가져오기 비교
<a name="SQLtoNoSQL.GetTableInfo"></a>

테이블이 사양에 따라 생성되었음을 확인할 수 있습니다. 관계형 데이터베이스에서는 테이블 스키마가 모두 표시됩니다. Amazon DynamoDB 테이블은 스키마가 없으므로 기본 키 속성만 표시됩니다.

**Topics**
+ [SQL에서 테이블에 대한 정보 가져오기](#SQLtoNoSQL.GetTableInfo.SQL)
+ [DynamoDB에서 테이블에 대한 정보 가져오기](#SQLtoNoSQL.GetTableInfo.DynamoDB)

## SQL에서 테이블에 대한 정보 가져오기
<a name="SQLtoNoSQL.GetTableInfo.SQL"></a>

대부분의 관계형 데이터베이스 관리 시스템(RDBMS)에서는 열, 데이터 형식, 기본 키 정의 등과 같은 테이블 구조를 설명할 수 있습니다. SQL에서는 이 작업을 하는 표준적 방법이 없습니다. 다만 많은 데이터베이스 시스템은 `DESCRIBE` 명령을 제공합니다. 다음은 MySQL 예제입니다.

```
DESCRIBE Music;
```

이는 모든 열 이름, 데이터 형식, 크기와 함께 테이블의 구조를 반환합니다.

```
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| Artist     | varchar(20) | NO   | PRI | NULL    |       |
| SongTitle  | varchar(30) | NO   | PRI | NULL    |       |
| AlbumTitle | varchar(25) | YES  |     | NULL    |       |
| Year       | int(11)     | YES  |     | NULL    |       |
| Price      | float       | YES  |     | NULL    |       |
| Genre      | varchar(10) | YES  |     | NULL    |       |
| Tags       | text        | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
```

이 테이블의 기본 키는 *Artist* 및 *SongTitle*로 구성됩니다.

## DynamoDB에서 테이블에 대한 정보 가져오기
<a name="SQLtoNoSQL.GetTableInfo.DynamoDB"></a>

DynamoDB에는 이와 비슷한 `DescribeTable` 작업이 있습니다. 이때는 테이블 이름 파라미터만 있으면 됩니다.

```
{
    TableName : "Music"
}
```

`DescribeTable`의 회신은 다음과 같습니다.

```
{
  "Table": {
    "AttributeDefinitions": [
      {
        "AttributeName": "Artist",
        "AttributeType": "S"
      },
      {
        "AttributeName": "SongTitle",
        "AttributeType": "S"
      }
    ],
    "TableName": "Music",
    "KeySchema": [
      {
        "AttributeName": "Artist",
        "KeyType": "HASH"  //Partition key
      },
      {
        "AttributeName": "SongTitle",
        "KeyType": "RANGE"  //Sort key
      }
    ],

    ...
```

`DescribeTable`은 또한 테이블의 인덱스, 할당된 처리량 설정, 대략적인 항목 카운트 및 기타 메타데이터에 관한 정보를 반환합니다.

# 테이블에 데이터를 쓸 때의 관계형(SQL) 데이터베이스와 DynamoDB 비교
<a name="SQLtoNoSQL.WriteData"></a>

관계형 데이터베이스 테이블에는 데이터의 *행*이 포함됩니다. 행은 *열*로 구성됩니다. Amazon DynamoDB 테이블에는 *항목*이 포함됩니다. 항목은 *속성*으로 구성됩니다.

이 섹션에서는 테이블에 하나의 행(또는 항목)을 쓰는 방법을 설명합니다.

**Topics**
+ [SQL에서 테이블에 데이터 쓰기](#SQLtoNoSQL.WriteData.SQL)
+ [DynamoDB에서 테이블에 데이터 쓰기](#SQLtoNoSQL.WriteData.DynamoDB)

## SQL에서 테이블에 데이터 쓰기
<a name="SQLtoNoSQL.WriteData.SQL"></a>

관계형 데이터베이스의 테이블은 행과 열로 이루어진 2차원 데이터 구조입니다. 일부 데이터베이스 관리 시스템은 보통 기본 JSON 또는 XML 데이터 형식을 사용하여 반정형 데이터 지원도 제공합니다. 하지만 구현의 세부적 내용은 공급업체마다 다릅니다.

SQL에서는 `INSERT` 문을 사용하여 테이블에 행을 추가합니다.

```
INSERT INTO Music
    (Artist, SongTitle, AlbumTitle,
    Year, Price, Genre,
    Tags)
VALUES(
    'No One You Know', 'Call Me Today', 'Somewhat Famous',
    2015, 2.14, 'Country',
    '{"Composers": ["Smith", "Jones", "Davis"],"LengthInSeconds": 214}'
);
```

이 테이블의 기본 키는 *Artist* 및 *SongTitle*로 구성됩니다. 이 열들의 값을 지정해야 합니다.

**참고**  
이 예제에서는 *Tags* 열을 사용하여 *Music* 테이블의 노래에 대한 반정형 데이터를 저장합니다. *Tags* 열은 TEXT 형식으로 정의되었으며 MySQL에 최대 65,535자를 저장할 수 있습니다.

## DynamoDB에서 테이블에 데이터 쓰기
<a name="SQLtoNoSQL.WriteData.DynamoDB"></a>

Amazon DynamoDB에서는 DynamoDB API나 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)(SQL 호환 쿼리 언어)을 사용하여 테이블에 항목을 추가할 수 있습니다.

------
#### [ DynamoDB API ]

DynamoDB API에서는 `PutItem` 작업을 사용하여 테이블에 항목을 추가합니다.

```
{
    TableName: "Music",
    Item: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today",
        "AlbumTitle":"Somewhat Famous",
        "Year": 2015,
        "Price": 2.14,
        "Genre": "Country",
        "Tags": {
            "Composers": [
                  "Smith",
                  "Jones",
                  "Davis"
            ],
            "LengthInSeconds": 214
        }
    }
}
```

이 테이블의 기본 키는 *Artist* 및 *SongTitle*로 구성됩니다. 이 속성들의 값을 지정해야 합니다.

다음은 이 `PutItem` 예제에 관해 알아야 할 주요 사항입니다.
+ DynamoDB는 JSON을 사용하여 문서에 대한 기본 지원을 제공합니다. 따라서 DynamoDB는 *Tags* 같은 반정형 데이터를 저장하는 데 적합합니다. JSON 문서 안에서 데이터를 가져오고 조작할 수도 있습니다.
+ *Music* 테이블에는 기본 키(*Artist* 및 *SongTitle*) 외에는 미리 정의된 속성이 없습니다.
+ 대부분의 SQL 데이터베이스는 트랜잭션 지향적입니다. `INSERT` 문을 발행하더라도 `COMMIT` 문을 발행하기 전까지는 데이터 수정이 영구적이지 않습니다. Amazon DynamoDB의 경우, DynamoDB가 HTTP 200 상태 코드(`OK`)로 응답하면 `PutItem` 작업의 결과가 영구적으로 적용됩니다.

다음은 몇 가지 다른 `PutItem` 예제입니다.

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

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

```
{
    TableName: "Music",
    Item: {
        "Artist": "The Acme Band",
        "SongTitle": "Still In Love",
        "AlbumTitle":"The Buck Starts Here",
        "Price": 2.47,
        "Genre": "Rock",
        "PromotionInfo": {
            "RadioStationsPlaying":[
                 "KHCR", "KBQX", "WTNR", "WJJH"
            ],
            "TourDates": {
                "Seattle": "20150625",
                "Cleveland": "20150630"
            },
            "Rotation": "Heavy"
        }
    }
}
```

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

**참고**  
DynamoDB는 `PutItem` 외에도 여러 항목을 동시에 쓰는 `BatchWriteItem` 작업을 지원합니다.

------
#### [ PartiQL for DynamoDB ]

PartiQL에서는 PartiQL `Insert` 문을 사용하여 `ExecuteStatement` 작업을 통해 테이블에 항목을 추가합니다.

```
INSERT into Music value {  
    'Artist': 'No One You Know',
    'SongTitle': 'Call Me Today',
    'AlbumTitle': 'Somewhat Famous',
    'Year' : '2015',
    'Genre' : 'Acme'
}
```

이 테이블의 기본 키는 *Artist* 및 *SongTitle*로 구성됩니다. 이 속성들의 값을 지정해야 합니다.

**참고**  
`Insert` 및 `ExecuteStatement`를 사용하는 코드 예제는 [DynamoDB의 PartiQL insert 문](ql-reference.insert.md) 섹션을 참조하세요.

------

# 테이블에서 데이터를 읽을 때의 관계형(SQL) 데이터베이스와 DynamoDB 비교
<a name="SQLtoNoSQL.ReadData"></a>

SQL에서는 `SELECT` 문을 사용하여 테이블에서 하나 이상의 항목을 가져올 수 있습니다. `WHERE` 절을 사용하여 반환되는 데이터를 결정합니다.

한편, Amazon DynamoDB를 사용하는 경우 데이터를 읽기 위해 다음과 같은 작업이 수행됩니다.
+ `ExecuteStatement`는 테이블에서 단일 또는 여러 개의 항목을 가져옵니다. `BatchExecuteStatement`는 단일 작업으로 서로 다른 테이블에서 여러 항목을 가져옵니다. 이 두 작업 모두 SQL 호환 쿼리 언어 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)을 사용합니다.
+ `GetItem` - 테이블에서 단일 항목을 가져옵니다. 이는 항목의 물리적 위치에 대한 직접 액세스를 제공하기 때문에 단일 항목을 읽는 가장 효율적인 방법입니다. (DynamoDB도 단일 작업으로 최대 100개의 `GetItem` 호출을 수행할 수 있는 `BatchGetItem` 작업을 제공합니다.)
+ `Query` - 특정 파티션 키가 있는 항목을 모두 가져옵니다. 이러한 항목 안에서 키를 정렬하고 데이터의 하위 집합만 가져오도록 조건을 적용할 수 있습니다. `Query`는 데이터가 저장된 파티션에 대한 빠르고 효율적인 액세스를 제공합니다. (자세한 내용은 [DynamoDB의 파티션 및 데이터 배포](HowItWorks.Partitions.md) 섹션을 참조하세요.)
+ `Scan` - 지정한 테이블의 모든 항목을 가져옵니다. (이 작업은 시스템 리소스를 많이 사용할 수 있으므로 큰 테이블에는 사용해서는 안 됩니다.)

**참고**  
관계형 데이터베이스의 경우, `SELECT` 문을 사용하여 여러 테이블의 데이터를 조인하고 결과를 반환할 수 있습니다. 조인은 관계형 모델의 기초입니다. 조인의 효율적 실행을 위해서는 데이터베이스와 그 애플리케이션의 성능을 지속적으로 튜닝해야 합니다. DynamoDB는 비관계형 NoSQL 데이터베이스로서 테이블 조인을 지원하지 않습니다. 그 대신 애플리케이션은 한 번에 한 테이블의 데이터를 읽습니다.

다음 섹션에서는 다양한 데이터 읽기 사용 사례를 설명하고, 관계형 데이터베이스와 DynamoDB로 이런 작업을 수행하는 방법을 살펴봅니다.

**Topics**
+ [프라이머리 키를 사용하여 항목 읽기 비교](SQLtoNoSQL.ReadData.SingleItem.md)
+ [테이블 쿼리 비교](SQLtoNoSQL.ReadData.Query.md)
+ [테이블 스캔 비교](SQLtoNoSQL.ReadData.Scan.md)

# 프라이머리 키를 사용하여 항목 읽기 비교
<a name="SQLtoNoSQL.ReadData.SingleItem"></a>

데이터베이스에 대한 공통적인 액세스 패턴 중 하나는 한 테이블에서 단일 항목을 읽어오는 것입니다. 원하는 항목의 기본 키를 지정해야 합니다.

**Topics**
+ [SQL에서 항목의 프라이머리 키를 사용하여 항목 읽기](#SQLtoNoSQL.ReadData.SingleItem.SQL)
+ [DynamoDB에서 항목의 프라이머리 키를 사용하여 항목 읽기](#SQLtoNoSQL.ReadData.SingleItem.DynamoDB)

## SQL에서 항목의 프라이머리 키를 사용하여 항목 읽기
<a name="SQLtoNoSQL.ReadData.SingleItem.SQL"></a>

SQL에서는 `SELECT` 문을 사용하여 테이블에서 데이터를 가져옵니다. 결과에 하나 이상의 열(또는 `*` 연산자를 사용하는 경우 모든 열)이 포함되도록 요청할 수 있습니다. `WHERE` 절은 반환할 행을 결정합니다.

다음은 *Music* 테이블에서 단일 행을 가져오는 `SELECT` 문입니다. `WHERE` 절은 기본 키 값을 지정합니다.

```
SELECT *
FROM Music
WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today'
```

이 쿼리를 수정하여 열의 하위 집합만 검색할 수 있습니다.

```
SELECT AlbumTitle, Year, Price
FROM Music
WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today'
```

이 테이블의 프라이머리 키는 *Artist* 및 *SongTitle*로 구성되어 있다는 점에 유의하세요.

## DynamoDB에서 항목의 프라이머리 키를 사용하여 항목 읽기
<a name="SQLtoNoSQL.ReadData.SingleItem.DynamoDB"></a>

Amazon DynamoDB에서는 DynamoDB API나 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)(SQL 호환 쿼리 언어)을 사용하여 테이블에서 항목을 읽을 수 있습니다.

------
#### [ DynamoDB API ]

DynamoDB API에서는 `PutItem` 작업을 사용하여 테이블에 항목을 추가합니다.

DynamoDB는 항목을 해당 프라이머리 키를 기준으로 가져오기 위한 `GetItem` 작업을 제공합니다. `GetItem`은 항목의 물리적 위치에 대한 직접 액세스를 제공하므로 매우 효율적입니다. (자세한 내용은 [DynamoDB의 파티션 및 데이터 배포](HowItWorks.Partitions.md) 섹션을 참조하세요.)

기본적으로 `GetItem`은 모든 속성과 함께 전체 항목을 반환합니다.

```
{
    TableName: "Music",
    Key: {
        "Artist": "No One You Know",
        "SongTitle": "Call Me Today"
    }
}
```

속성의 일부만 반환하는 `ProjectionExpression` 파라미터를 추가할 수 있습니다.

```
{
    TableName: "Music",
    Key: {
        "Artist": "No One You Know",
        "SongTitle": "Call Me Today"
    },
    "ProjectionExpression": "AlbumTitle, Year, Price"
}
```

이 테이블의 프라이머리 키는 *Artist* 및 *SongTitle*로 구성되어 있다는 점에 유의하세요.

DynamoDB `GetItem` 작업은 매우 효율적입니다. 프라이머리 키 값을 사용하여 해당 항목의 정확한 스토리지 위치를 확인하고 그 위치에서 직접 항목을 가져옵니다. SQL `SELECT` 문도 기본 키 값을 기준으로 항목을 가져오는 경우에는 마찬가지로 효율적입니다.

SQL `SELECT` 문은 다양한 쿼리 및 테이블 스캔을 지원합니다. DynamoDB는 [테이블 쿼리 비교](SQLtoNoSQL.ReadData.Query.md) 및 [테이블 스캔 비교](SQLtoNoSQL.ReadData.Scan.md)에 설명된 대로 `Query` 및 `Scan` 작업을 통해 이와 비슷한 기능을 제공합니다.

SQL `SELECT` 문은 테이블 조인을 수행하여 한 번에 여러 테이블에서 데이터를 가져올 수 있습니다. 조인은 데이터베이스 테이블들이 정규화되어 있고 테이블 간 관계가 명확한 경우에 가장 효과적입니다. 그러나 하나의 `SELECT` 문에서 지나치게 많은 테이블을 조인하는 경우, 애플리케이션 성능이 영향을 받을 수 있습니다. 이런 문제는 데이터베이스 복제, 구체화된 보기 또는 쿼리 다시 쓰기를 사용하여 해결할 수 있습니다.

DynamoDB는 비관계형 데이터베이스로, 테이블 조인을 지원하지 않습니다. 기존 애플리케이션을 관계형 데이터베이스에서 DynamoDB로 마이그레이션하는 경우, 조인의 필요성을 제거하기 위해 데이터 모델을 비정규화해야 합니다.

------
#### [ PartiQL for DynamoDB ]

PartiQL에서는 PartiQL `Select` 문을 사용하여 `ExecuteStatement` 작업을 통해 테이블에서 항목을 읽습니다.

```
SELECT AlbumTitle, Year, Price
FROM Music
WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today'
```

이 테이블의 프라이머리 키는 Artist 및 SongTitle로 구성되어 있다는 점에 유의하세요.

**참고**  
 Select PartiQL 문은 DynamoDB 테이블을 쿼리하거나 스캔하는 데에도 사용할 수 있습니다.

`Select` 및 `ExecuteStatement`를 사용하는 코드 예제는 [DynamoDB의 PartiQL select 문](ql-reference.select.md) 섹션을 참조하세요.

------

# 테이블 쿼리 비교
<a name="SQLtoNoSQL.ReadData.Query"></a>

또 다른 공통적인 액세스 패턴은 쿼리 기준에 기반하여 한 테이블에서 복수의 항목을 읽어오는 것입니다.

**Topics**
+ [SQL에서 테이블 쿼리](#SQLtoNoSQL.ReadData.Query.SQL)
+ [DynamoDB에서 테이블 쿼리](#SQLtoNoSQL.ReadData.Query.DynamoDB)

## SQL에서 테이블 쿼리
<a name="SQLtoNoSQL.ReadData.Query.SQL"></a>

SQL `SELECT` 문을 사용하여 키 열, 키 이외 열 또는 임의의 조합에서 쿼리를 수행할 수 있습니다. 다음 예제와 같이 `WHERE` 절은 반환되는 행을 결정합니다.

```
/* Return a single song, by primary key */

SELECT * FROM Music
WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today';
```

```
/* Return all of the songs by an artist */

SELECT * FROM Music
WHERE Artist='No One You Know';
```

```
/* Return all of the songs by an artist, matching first part of title */

SELECT * FROM Music
WHERE Artist='No One You Know' AND SongTitle LIKE 'Call%';
```

```
/* Return all of the songs by an artist, only if the price is less than 1.00 */

SELECT * FROM Music
WHERE Artist='No One You Know'
AND Price < 1.00;
```

이 테이블의 프라이머리 키는 *Artist* 및 *SongTitle*로 구성되어 있다는 점에 유의하세요.

## DynamoDB에서 테이블 쿼리
<a name="SQLtoNoSQL.ReadData.Query.DynamoDB"></a>

Amazon DynamoDB에서는 DynamoDB API나 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)(SQL 호환 쿼리 언어)을 사용하여 테이블에서 항목을 쿼리할 수 있습니다.

------
#### [ DynamoDB API ]

Amazon DynamoDB의 `Query` 작업을 사용해도 비슷한 방법으로 데이터를 가져올 수 있습니다. `Query` 작업은 데이터가 저장된 물리적 위치에 대한 빠르고 효율적인 액세스를 제공합니다. 자세한 내용은 [DynamoDB의 파티션 및 데이터 배포](HowItWorks.Partitions.md) 섹션을 참조하세요.

테이블 또는 보조 인덱스와 함께 `Query`를 사용할 수 있습니다. 파티션 키 값에는 등식 조건을 지정해야 하며 지정된 경우 정렬 키 속성에 대해 다른 조건을 선택적으로 지정할 수 있습니다.

`KeyConditionExpression` 파라미터는 쿼리하려는 키 값을 지정합니다. 선택 사항인 `FilterExpression`을 사용하면 반환 전에 일정 항목을 결과에서 제거할 수 있습니다.

DynamoDB에서는 `ExpressionAttributeValues`를 표현식 파라미터(`KeyConditionExpression`, `FilterExpression` 등)에서 자리 표시자로 사용해야 합니다. 이는 런타임에 실제 값을 `SELECT` 문으로 대체하는 관계형 데이터베이스의 *바인드 변수* 사용과 유사합니다.

이 테이블의 프라이머리 키는 *Artist* 및 *SongTitle*로 구성되어 있다는 점에 유의하세요.

다음은 몇 가지 DynamoDB `Query` 예제입니다.

```
// Return a single song, by primary key

{
    TableName: "Music",
    KeyConditionExpression: "Artist = :a and SongTitle = :t",
    ExpressionAttributeValues: {
        ":a": "No One You Know",
        ":t": "Call Me Today"
    }
}
```

```
// Return all of the songs by an artist

{
    TableName: "Music",
    KeyConditionExpression: "Artist = :a",
    ExpressionAttributeValues: {
        ":a": "No One You Know"
    }
}
```

```
// Return all of the songs by an artist, matching first part of title

{
    TableName: "Music",
    KeyConditionExpression: "Artist = :a and begins_with(SongTitle, :t)",
    ExpressionAttributeValues: {
        ":a": "No One You Know",
        ":t": "Call"
    }
}
```

```
// Return all of the songs by an artist, only if the price is less than 1.00

{
    TableName: "Music",
    KeyConditionExpression: "Artist = :a",
    FilterExpression: "Price < :p",
    ExpressionAttributeValues: {
        ":a": "No One You Know",
        ":p": 1.00
    }
}
```

**참고**  
`FilterExpression`은 `Query`가 일치하는 항목을 읽은 후 적용되므로 소비되는 읽기 용량을 줄이지 않습니다. 가능한 경우 범위 조건이 효율적인 쿼리를 위해 정렬 키에 `KeyConditionExpression`을 사용하도록 데이터를 모델링합니다. 자세한 내용은 [DynamoDB에서 테이블 쿼리](Query.md) 섹션을 참조하세요.

------
#### [ PartiQL for DynamoDB ]

PartiQL에서는 `ExecuteStatement` 작업과 파티션 키에 `Select` 문을 사용하여 쿼리를 수행할 수 있습니다.

```
SELECT AlbumTitle, Year, Price
FROM Music
WHERE Artist='No One You Know'
```

이와 같이 `SELECT` 문을 사용하면 이 특정 `Artist`와 연결된 모든 곡이 반환됩니다.

`Select` 및 `ExecuteStatement`를 사용하는 코드 예제는 [DynamoDB의 PartiQL select 문](ql-reference.select.md) 섹션을 참조하세요.

------

# 테이블 스캔 비교
<a name="SQLtoNoSQL.ReadData.Scan"></a>

SQL에서 `SELECT` 절이 없는 `WHERE` 문은 테이블의 모든 행을 반환합니다. Amazon DynamoDB에서 `Scan` 작업도 동일한 작업을 수행합니다. 두 경우 모두 모든 항목 또는 일부 항목만 검색할 수 있습니다.

SQL 데이터베이스를 사용하건 NoSQL 데이터베이스를 사용하건 스캔은 시스템 리소스를 많이 사용할 수 있으므로 꼭 필요할 때만 사용해야 합니다. 스캔이 적절하거나(작은 테이블을 스캔할 때) 불가피한(데이터를 대량으로 내보낼 때) 경우도 있습니다. 하지만 일반적으로는 스캔 수행을 피할 수 있도록 애플리케이션을 설계해야 합니다. 자세한 내용은 [DynamoDB에서 테이블 쿼리](Query.md) 섹션을 참조하세요.

**참고**  
대량 내보내기를 수행하면 파티션당 하나 이상의 파일이 만들어집니다. 각 파일의 모든 항목은 해당 파티션의 해시된 키스페이스에서 가져온 것입니다.

**Topics**
+ [SQL에서 테이블 스캔](#SQLtoNoSQL.ReadData.Scan.SQL)
+ [DynamoDB에서 테이블 스캔](#SQLtoNoSQL.ReadData.Scan.DynamoDB)

## SQL에서 테이블 스캔
<a name="SQLtoNoSQL.ReadData.Scan.SQL"></a>

SQL에서는 `WHERE` 절을 지정하지 않고 `SELECT` 문을 사용하여 테이블을 스캔하고 모든 데이터를 가져올 수 있습니다. 결과에 하나 이상의 열이 포함되도록 요청할 수 있습니다. 또는 와일드카드 문자(\$1)를 사용하는 경우 모든 열을 요청할 수 있습니다.

다음은 `SELECT` 문 사용의 예입니다.

```
/* Return all of the data in the table */
SELECT * FROM Music;
```

```
/* Return all of the values for Artist and Title */
SELECT Artist, Title FROM Music;
```

## DynamoDB에서 테이블 스캔
<a name="SQLtoNoSQL.ReadData.Scan.DynamoDB"></a>

Amazon DynamoDB에서는 DynamoDB API나 SQL [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)(호환 쿼리 언어)을 사용하여 테이블에서 스캔을 수행할 수 있습니다.

------
#### [ DynamoDB API ]

DynamoDB API에서는 `Scan` 작업을 통해 테이블 또는 보조 인덱스의 모든 항목에 액세스하여 하나 이상의 항목 및 항목 속성을 반환합니다.

```
// Return all of the data in the table
{
    TableName:  "Music"
}
```

```
// Return all of the values for Artist and Title
{
    TableName:  "Music",
    ProjectionExpression: "Artist, Title"
}
```

`Scan` 작업도 결과에 표시되기를 원치 않는 항목을 삭제하는 데 사용할 수 있는 `FilterExpression` 파라미터를 제공합니다. `FilterExpression`은 스캔이 수행된 후 결과가 반환되기 전에 적용됩니다. (큰 테이블에는 사용하지 않는 것이 좋습니다. 일치하는 소수의 항목이 반환되더라도 여전히 전체 `Scan`에 대한 요금이 청구됩니다.)

------
#### [ PartiQL for DynamoDB ]

PartiQL에서는 `ExecuteStatement` 작업을 통해 `Select` 문을 사용하여 테이블의 모든 내용을 반환하여 스캔을 수행합니다.

```
SELECT AlbumTitle, Year, Price
FROM Music
```

이 문은 Music 테이블에서 모든 항목을 반환합니다.

`Select` 및 `ExecuteStatement`를 사용하는 코드 예제는 [DynamoDB의 PartiQL select 문](ql-reference.select.md) 섹션을 참조하세요.

------

# 인덱스 관리 시 관계형(SQL) 데이터베이스와 DynamoDB 비교
<a name="SQLtoNoSQL.Indexes"></a>

인덱스는 대체 쿼리 패턴에 대한 액세스를 제공하고, 쿼리 속도를 높일 수 있습니다. 이 섹션에서는 SQL에서의 인덱스 생성 및 사용을 Amazon DynamoDB의 경우와 비교 대조합니다.

관계형 데이터베이스를 사용하건 DynamoDB를 사용하건 인덱스 생성에는 신중을 기해야 합니다. 테이블에서 쓰기가 이루어질 때마다 테이블의 모든 인덱스가 업데이트되어야 합니다. 테이블이 크고 쓰기 작업이 많은 환경에서는 시스템 리소스가 많이 사용될 수 있습니다. 읽기 전용 또는 읽기가 주를 이루는 환경에서는 그 정도로 문제가 되지는 않지만 인덱스가 단순히 공간을 차지하는 것이 아니라 실제로 애플리케이션에 의해 사용되어야 합니다.

**Topics**
+ [인덱스 생성 시 관계형(SQL) 데이터베이스와 DynamoDB 비교](#SQLtoNoSQL.Indexes.Creating)
+ [인덱스를 쿼리하고 스캔할 때 관계형(SQL) 데이터베이스와 DynamoDB 비교](#SQLtoNoSQL.Indexes.QueryAndScan)

## 인덱스 생성 시 관계형(SQL) 데이터베이스와 DynamoDB 비교
<a name="SQLtoNoSQL.Indexes.Creating"></a>

SQL의 `CREATE INDEX` 문을 Amazon DynamoDB의 `UpdateTable` 작업과 비교합니다.

**Topics**
+ [SQL에서 인덱스 생성](#SQLtoNoSQL.Indexes.Creating.SQL)
+ [DynamoDB에서 인덱스 생성](#SQLtoNoSQL.Indexes.Creating.DynamoDB)

### SQL에서 인덱스 생성
<a name="SQLtoNoSQL.Indexes.Creating.SQL"></a>

관계형 데이터베이스에서 인덱스는 한 테이블의 여러 열에서 빠른 쿼리를 수행할 수 있는 데이터 구조입니다. `CREATE INDEX` SQL 문을 사용하면 기존 테이블에 인덱스를 추가하여 열을 인덱싱하도록 지정할 수 있습니다. 인덱스가 생성된 후 테이블에서 평소처럼 데이터를 쿼리할 수 있지만 데이터베이스는 이제 전체 테이블을 스캔하는 대신 인덱스를 사용하여 지정된 행을 테이블에서 빠르게 찾을 수 있습니다.

인덱스 생성 후 데이터베이스는 인덱스를 유지합니다. 테이블의 데이터를 수정할 때마다 테이블의 변경 사항을 반영하여 인덱스도 자동으로 수정됩니다.

MySQL에서 인덱스를 생성하는 방법은 다음과 같습니다.

```
CREATE INDEX GenreAndPriceIndex
ON Music (genre, price);
```

### DynamoDB에서 인덱스 생성
<a name="SQLtoNoSQL.Indexes.Creating.DynamoDB"></a>

DynamoDB에서는 비슷한 용도의 *보조 인덱스*를 생성하고 사용할 수 있습니다.

DynamoDB의 인덱스는 관계형 데이터베이스의 인덱스와 다릅니다. 보조 인덱스를 생성할 때는 해당 키 속성, 즉 파티션 키와 정렬 키를 지정해야 합니다. 보조 인덱스를 생성한 후 테이블과 마찬가지로 보조 인덱스를 `Query` 또는 `Scan`할 수 있습니다. DynamoDB에는 쿼리 최적화 프로그램이 없으므로 보조 인덱스는 `Query` 또는 `Scan`할 때만 사용됩니다.

DynamoDB는 다음과 같이 두 종류의 인덱스를 지원합니다.
+ 글로벌 보조 인덱스 - 이 인덱스의 기본 키는 해당 테이블의 두 가지 속성 중 어느 것이나 될 수 있습니다.
+ 로컬 보조 인덱스 - 이 인덱스의 파티션 키는 해당 테이블의 파티션 키와 동일해야 합니다. 하지만 정렬 키는 다른 속성이어도 됩니다.

DynamoDB에서는 보조 인덱스의 데이터가 해당 테이블과 최종적으로 일관되어야 합니다. 테이블이나 로컬 보조 인덱스에서는 강력히 일관된 `Query` 또는 `Scan` 작업을 요청할 수 있습니다. 그러나 글로벌 보조 인덱스는 최종 일관성만 지원합니다.

`UpdateTable` 작업을 사용하고 `GlobalSecondaryIndexUpdates`를 지정하여 글로벌 보조 인덱스를 기존 테이블에 추가할 수 있습니다.

```
{
    TableName: "Music",
    AttributeDefinitions:[
        {AttributeName: "Genre", AttributeType: "S"},
        {AttributeName: "Price", AttributeType: "N"}
    ],
    GlobalSecondaryIndexUpdates: [
        {
            Create: {
                IndexName: "GenreAndPriceIndex",
                KeySchema: [
                    {AttributeName: "Genre", KeyType: "HASH"}, //Partition key
                    {AttributeName: "Price", KeyType: "RANGE"}, //Sort key
                ],
                Projection: {
                    "ProjectionType": "ALL"
                },
                ProvisionedThroughput: {                                // Only specified if using provisioned mode
                    "ReadCapacityUnits": 1,"WriteCapacityUnits": 1
                }
            }
        }
    ]
}
```

다음 파라미터를 `UpdateTable`에 입력해야 합니다.
+ `TableName` - 인덱스가 연동될 테이블
+ `AttributeDefinitions` - 인덱스의 키 스키마 속성에 대한 데이터 형식
+ `GlobalSecondaryIndexUpdates` - 생성하려는 인덱스에 관한 세부 정보
  + `IndexName` - 인덱스의 이름
  + `KeySchema` - 인덱스 기본 키에 사용되는 속성
  + `Projection` - 테이블에서 인덱스로 복사되는 속성. 이 경우, `ALL`은 테이블에서 인덱스로 복사되는 모든 속성을 뜻합니다.
  + `ProvisionedThroughput (for provisioned tables)` - 이 인덱스에 필요한 초당 읽기 및 쓰기 수. (이것은 테이블의 할당 처리량 설정과 별개입니다.) 

이 작업에는 테이블의 데이터를 새 인덱스에 채우기가 포함됩니다. 채우기 중에 테이블은 사용 가능한 상태를 유지합니다. 하지만 인덱스의 `Backfilling` 속성이 true에서 false로 바뀔 때까지는 인덱스를 사용할 수 없습니다. `DescribeTable` 작업을 사용하여 이 속성을 볼 수 있습니다.

## 인덱스를 쿼리하고 스캔할 때 관계형(SQL) 데이터베이스와 DynamoDB 비교
<a name="SQLtoNoSQL.Indexes.QueryAndScan"></a>

Amazon DynamoDB의 `Query` 및 `Scan` 작업과 SQL의 SELECT 문을 사용한 인덱스 쿼리 및 스캔을 비교합니다.

**Topics**
+ [SQL에서 인덱스 쿼리 및 스캔](#SQLtoNoSQL.Indexes.QueryAndScan.SQL)
+ [DynamoDB에서 인덱스 쿼리 및 스캔](#SQLtoNoSQL.Indexes.QueryAndScan.DynamoDB)

### SQL에서 인덱스 쿼리 및 스캔
<a name="SQLtoNoSQL.Indexes.QueryAndScan.SQL"></a>

관계형 데이터베이스에서는 직접 인덱스를 다루지 않습니다. 그 대신 `SELECT` 문을 실행하여 테이블을 쿼리하며, 쿼리 옵티마이저가 인덱스를 사용할 수 있습니다.

*쿼리 옵티마이저*는 사용 가능한 인덱스를 평가하고 그 인덱스로 쿼리 속도를 높일 수 있는지 파악하는 RDBMS(관계형 데이터베이스 관리 시스템)의 구성 요소입니다. 인덱스를 사용하여 쿼리 속도를 높일 수 있는 경우, RDBMS는 먼저 인덱스에 액세스한 다음 인덱스를 사용해 테이블에서 데이터를 찾습니다.

다음은 *GenreAndPriceIndex*를 사용해 성능을 개선할 수 있는 몇 가지 SQL 문입니다. *Music* 테이블에 충분한 데이터가 있어서 쿼리 옵티마이저가 전체 테이블을 단순히 스캔하기보다는 이 인덱스를 사용하기로 결정한다고 가정합니다.

```
/* All of the rock songs */

SELECT * FROM Music
WHERE Genre = 'Rock';
```

```
/* All of the cheap country songs */

SELECT Artist, SongTitle, Price FROM Music
WHERE Genre = 'Country' AND Price < 0.50;
```

### DynamoDB에서 인덱스 쿼리 및 스캔
<a name="SQLtoNoSQL.Indexes.QueryAndScan.DynamoDB"></a>

DynamoDB에서는 테이블에서와 동일하게 인덱스에서 직접 `Query` 및 `Scan` 작업을 수행합니다. DynamoDB API 또는 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)(SQL 호환 쿼리 언어)을 사용하여 인덱스를 쿼리하거나 스캔할 수 있습니다. `TableName`과 `IndexName`을 모두 지정해야 합니다.

다음은 DynamoDB의 *GenreAndPriceIndex*에 대한 몇 가지 쿼리입니다. (이 인덱스의 키 스키마는 *Genre*와 *Price*로 구성됩니다.)

------
#### [ DynamoDB API ]

```
// All of the rock songs

{
    TableName: "Music",
    IndexName: "GenreAndPriceIndex",
    KeyConditionExpression: "Genre = :genre",
    ExpressionAttributeValues: {
        ":genre": "Rock"
    },
};
```

이 예제에서는 속성 전부가 아니라 일부만 결과에 표시하려 한다는 것을 나타내기 위해 `ProjectionExpression`을 사용합니다.

```
// All of the cheap country songs

{
    TableName: "Music",
    IndexName: "GenreAndPriceIndex",
    KeyConditionExpression: "Genre = :genre and Price < :price",
    ExpressionAttributeValues: {
        ":genre": "Country",
        ":price": 0.50
    },
    ProjectionExpression: "Artist, SongTitle, Price"
};
```

다음은 *GenreAndPriceIndex*에서의 스캔입니다.

```
// Return all of the data in the index

{
    TableName:  "Music",
    IndexName: "GenreAndPriceIndex"
}
```

------
#### [ PartiQL for DynamoDB ]

PartiQL에서는 PartiQL `Select` 문을 사용하여 인덱스에 대한 쿼리 및 스캔을 수행합니다.

```
// All of the rock songs

SELECT * 
FROM Music.GenreAndPriceIndex
WHERE Genre = 'Rock'
```

```
// All of the cheap country songs

SELECT * 
FROM Music.GenreAndPriceIndex
WHERE Genre = 'Rock' AND Price < 0.50
```

다음은 *GenreAndPriceIndex*에서의 스캔입니다.

```
// Return all of the data in the index

SELECT *
FROM Music.GenreAndPriceIndex
```

**참고**  
`Select`를 사용하는 코드 예제는 [DynamoDB의 PartiQL select 문](ql-reference.select.md) 섹션을 참조하세요.

------

# 테이블에서 데이터를 수정할 때 관계형(SQL) 데이터베이스와 DynamoDB 비교
<a name="SQLtoNoSQL.UpdateData"></a>

SQL 언어는 데이터 수정을 위한 `UPDATE` 문을 제공합니다. Amazon DynamoDB는 비슷한 태스크를 위해 `UpdateItem` 작업을 사용합니다.

**Topics**
+ [SQL에서 테이블의 데이터 수정](#SQLtoNoSQL.UpdateData.SQL)
+ [DynamoDB에서 테이블의 데이터 수정](#SQLtoNoSQL.UpdateData.DynamoDB)

## SQL에서 테이블의 데이터 수정
<a name="SQLtoNoSQL.UpdateData.SQL"></a>

SQL에서는 `UPDATE` 문을 사용하여 하나 이상의 행을 수정합니다. `SET` 절은 하나 이상의 열의 새로운 값을 지정하고, `WHERE` 절은 어떤 행이 수정되는지 결정합니다. 다음은 예입니다.

```
UPDATE Music
SET RecordLabel = 'Global Records'
WHERE Artist = 'No One You Know' AND SongTitle = 'Call Me Today';
```

`WHERE` 절과 일치하는 행이 없으면 `UPDATE` 문은 영향을 미치지 않습니다.

## DynamoDB에서 테이블의 데이터 수정
<a name="SQLtoNoSQL.UpdateData.DynamoDB"></a>

DynamoDB에서는 클래식 API나 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)(SQL 호환 쿼리 언어)을 사용하여 단일 항목을 수정할 수 있습니다. 복수의 항목을 수정하려면 복수의 작업을 사용해야 합니다.

------
#### [ DynamoDB API ]

DynamoDB API에서는 `UpdateItem` 작업을 사용하여 단일 항목을 수정합니다.

```
{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET RecordLabel = :label",
    ExpressionAttributeValues: {
        ":label": "Global Records"
    }
}
```

수정할 항목의 `Key` 속성과 속성 값을 지정하는 `UpdateExpression`을 지정해야 합니다. `UpdateItem`은 'upsert' 작업처럼 동작합니다. 즉 항목이 테이블에 존재하면 업데이트되지만 그렇지 않으면 새 항목이 추가(삽입)됩니다.

`UpdateItem`은 *조건부 쓰기*를 지원하는데, 특정 `ConditionExpression`이 true로 평가되는 경우에 한해 작업이 성공합니다. 예를 들어, 다음 `UpdateItem` 작업은 노래의 가격이 2.00 이상이 아니면 업데이트를 수행하지 않습니다.

```
{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET RecordLabel = :label",
    ConditionExpression: "Price >= :p",
    ExpressionAttributeValues: {
        ":label": "Global Records",
        ":p": 2.00
    }
}
```

`UpdateItem`은 *원자성 카운터* 즉, 증가하거나 감소할 수 있는 `Number` 형식의 속성도 지원합니다. 원자성 카운터는 여러 가지 면에서 SQL 데이터베이스의 시퀀스 발생기, 자격 증명 열 또는 자동 증분 필드와 유사합니다.

다음은 `UpdateItem` 작업을 통해 새 속성(*Plays*)을 초기화하여 노래가 재생된 횟수를 추적하는 예제입니다.

```
{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET Plays = :val",
    ExpressionAttributeValues: {
        ":val": 0
    },
    ReturnValues: "UPDATED_NEW"
}
```

`ReturnValues` 파라미터는 업데이트된 속성의 새 값을 반환하는 `UPDATED_NEW`로 설정됩니다. 이 경우에는 0을 반환합니다.

누군가가 이 노래를 재생할 때마다 다음 `UpdateItem` 작업을 사용하여 *Plays*를 1씩 증가시킬 수 있습니다.

```
{
    TableName: "Music",
    Key: {
        "Artist":"No One You Know",
        "SongTitle":"Call Me Today"
    },
    UpdateExpression: "SET Plays = Plays + :incr",
    ExpressionAttributeValues: {
        ":incr": 1
    },
    ReturnValues: "UPDATED_NEW"
}
```

------
#### [ PartiQL for DynamoDB ]

PartiQL에서는 PartiQL `Update` 문을 사용하여 `ExecuteStatement` 작업을 통해 테이블의 항목을 수정합니다.

이 테이블의 기본 키는 *Artist* 및 *SongTitle*로 구성됩니다. 이 속성들의 값을 지정해야 합니다.

```
UPDATE Music
SET RecordLabel ='Global Records'
WHERE Artist='No One You Know' AND SongTitle='Call Me Today'
```

다음 예와 같이 여러 필드를 한 번에 수정할 수도 있습니다.

```
UPDATE Music
SET RecordLabel = 'Global Records'
SET AwardsWon = 10
WHERE Artist ='No One You Know' AND SongTitle='Call Me Today'
```

`Update`은 *원자성 카운터* 즉, 증가하거나 감소할 수 있는 `Number` 형식의 속성도 지원합니다. 원자성 카운터는 여러 가지 면에서 SQL 데이터베이스의 시퀀스 발생기, 자격 증명 열 또는 자동 증분 필드와 유사합니다.

다음은 `Update` 문을 통해 새 속성(*Plays*)을 초기화하여 노래가 재생된 횟수를 추적하는 예제입니다.

```
UPDATE Music
SET Plays = 0
WHERE Artist='No One You Know' AND SongTitle='Call Me Today'
```

누군가가 이 노래를 재생할 때마다 다음 `Update` 문을 사용하여 *Plays*를 1씩 증가시킬 수 있습니다.

```
UPDATE Music
SET Plays = Plays + 1
WHERE Artist='No One You Know' AND SongTitle='Call Me Today'
```

**참고**  
`Update` 및 `ExecuteStatement`를 사용하는 코드 예제는 [DynamoDB의 PartiQL update 문](ql-reference.update.md) 섹션을 참조하세요.

------

# 테이블에서 데이터를 삭제할 때 관계형(SQL) 데이터베이스와 DynamoDB 비교
<a name="SQLtoNoSQL.DeleteData"></a>

SQL에서 `DELETE` 문은 테이블에서 하나 이상의 행을 제거합니다. Amazon DynamoDB에서는 `DeleteItem` 작업을 사용하여 항목을 한 번에 하나씩 삭제합니다.

**Topics**
+ [SQL에서 테이블의 데이터 삭제](#SQLtoNoSQL.DeleteData.SQL)
+ [DynamoDB에서 테이블의 데이터 삭제](#SQLtoNoSQL.DeleteData.DynamoDB)

## SQL에서 테이블의 데이터 삭제
<a name="SQLtoNoSQL.DeleteData.SQL"></a>

SQL에서는 `DELETE` 문을 사용하여 하나 이상의 행을 삭제합니다. `WHERE` 절은 수정하려는 행을 결정합니다. 다음은 예입니다.

```
DELETE FROM Music
WHERE Artist = 'The Acme Band' AND SongTitle = 'Look Out, World';
```

여러 열을 삭제하도록 `WHERE` 절을 수정할 수 있습니다. 예를 들어, 다음 예제와 같이 특정 아티스트의 모든 노래를 삭제할 수 있습니다.

```
DELETE FROM Music WHERE Artist = 'The Acme Band'
```

## DynamoDB에서 테이블의 데이터 삭제
<a name="SQLtoNoSQL.DeleteData.DynamoDB"></a>

DynamoDB에서는 클래식 API나 [PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html)(SQL 호환 쿼리 언어)을 사용하여 단일 항목을 삭제할 수 있습니다. 복수의 항목을 수정하려면 복수의 작업을 사용해야 합니다.

------
#### [ DynamoDB API ]

DynamoDB API에서는 `DeleteItem` 작업을 사용하여 테이블에서 데이터를 한 번에 한 항목씩 삭제합니다. 항목의 기본 키 값을 지정해야 합니다.

```
{
    TableName: "Music",
    Key: {
        Artist: "The Acme Band",
        SongTitle: "Look Out, World"
    }
}
```

**참고**  
Amazon DynamoDB는 `DeleteItem` 외에도 여러 항목을 동시에 삭제하는 `BatchWriteItem` 작업을 지원합니다.

`DeleteItem`은 *조건부 쓰기*를 지원하는데, 특정 `ConditionExpression`이 true로 평가되는 경우에 한해 작업이 성공합니다. 예를 들어, 다음 `DeleteItem` 작업은 *RecordLabel* 속성이 있는 항목만 삭제합니다.

```
{
    TableName: "Music",
    Key: {
        Artist: "The Acme Band",
        SongTitle: "Look Out, World"
    },
   ConditionExpression: "attribute_exists(RecordLabel)"
}
```

------
#### [ PartiQL for DynamoDB ]

PartiQL에서는 `ExecuteStatement` 작업을 통해 `Delete` 문을 사용하여 테이블에서 데이터를 한 번에 한 항목씩 삭제합니다. 항목의 기본 키 값을 지정해야 합니다.

이 테이블의 기본 키는 *Artist* 및 *SongTitle*로 구성됩니다. 이 속성들의 값을 지정해야 합니다.

```
DELETE FROM Music
WHERE Artist = 'Acme Band' AND SongTitle = 'PartiQL Rocks'
```

작업에 대한 추가 조건을 지정할 수 있습니다. 다음 `DELETE` 작업은 *Awards*가 11 이상인 경우에만 항목을 삭제합니다.

```
DELETE FROM Music
WHERE Artist = 'Acme Band' AND SongTitle = 'PartiQL Rocks' AND Awards > 11
```

**참고**  
`DELETE` 및 `ExecuteStatement`를 사용하는 코드 예제는 [DynamoDB의 PartiQL delete 문](ql-reference.delete.md) 섹션을 참조하세요.

------

# 테이블 제거 시 관계형(SQL) 데이터베이스와 DynamoDB 비교
<a name="SQLtoNoSQL.RemoveTable"></a>

SQL에서는 `DROP TABLE` 문을 사용하여 테이블을 제거합니다. Amazon DynamoDB에서는 `DeleteTable` 작업을 사용합니다.

**Topics**
+ [SQL에서 테이블 제거](#SQLtoNoSQL.RemoveTable.SQL)
+ [DynamoDB에서 테이블 제거](#SQLtoNoSQL.RemoveTable.DynamoDB)

## SQL에서 테이블 제거
<a name="SQLtoNoSQL.RemoveTable.SQL"></a>

테이블이 더 이상 필요하지 않아 영구적으로 삭제하려는 경우 SQL에서 `DROP TABLE` 문을 사용합니다.

```
DROP TABLE Music;
```

테이블이 삭제되고 나면 복구할 수 없습니다. (일부 관계형 데이터베이스에서 `DROP TABLE` 작업 실행을 취소할 수는 있지만 일부 공급업체에 한정된 기능으로 널리 구현되지는 않습니다.)

## DynamoDB에서 테이블 제거
<a name="SQLtoNoSQL.RemoveTable.DynamoDB"></a>

DynamoDB에는 이와 비슷한 `DeleteTable` 작업이 있습니다. 다음 예에서는 테이블이 영구적으로 삭제됩니다.

```
{
    TableName: "Music"
}
```

# Amazon DynamoDB 학습 리소스 및 도구
<a name="AdditionalResources"></a>

DynamoDB를 이해하고 작업하는 데 도움이 되는 다음과 같은 추가 리소스를 사용할 수 있습니다.

**Topics**
+ [코딩 및 시각화를 위한 도구](#AdditionalResources.Tools)
+ [권장 가이드 문서](#AdditionalResources.PrescriptiveGuidance)
+ [지식 센터 문서](#AdditionalResources.KnowledgeCenter)
+ [블로그 게시물, 리포지토리 및 가이드](#AdditionalResources.Guides)
+ [데이터 모델링 및 디자인 패턴 프레젠테이션](#AdditionalResources.DataModeling)
+ [교육 과정](#AdditionalResources.Training)

## 코딩 및 시각화를 위한 도구
<a name="AdditionalResources.Tools"></a>

DynamoDB 작업에 다음과 같은 코딩 및 시각화 도구를 사용할 수 있습니다.
+ [Amazon DynamoDB용 NoSQL Workbench](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html) - DynamoDB 테이블을 디자인, 생성, 쿼리, 관리하는 데 도움이 되는 통합된 시각적 도구이며, 데이터 모델링, 데이터 시각화 및 쿼리 개발 기능을 제공합니다.
+ [Dynobase](https://dynobase.dev/) - 간단하게 DynamoDB 테이블을 보고 작업하고, 앱 코드를 작성하고, 실시간 확인을 통해 레코드를 편집할 수 있는 데스크톱 도구입니다.
+ [DynamoDB Toolbox](https://github.com/jeremydaly/dynamodb-toolbox) - 데이터 모델링 작업과 JavaScript 및 Node.js에서의 작업에 유용한 유틸리티를 제공하는 Jeremy Daly의 프로젝트입니다.
+ [DynamoDB Streams 프로세서](https://github.com/jeremydaly/dynamodb-streams-processor) - [DynamoDB 스트림](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html) 작업에 사용할 수 있는 간단한 도구입니다.

## 권장 가이드 문서
<a name="AdditionalResources.PrescriptiveGuidance"></a>

AWS 권장 가이드에서는 프로젝트를 가속화하는 데 도움이 되는 오랜 시간 동안 검증된 전략, 가이드 및 패턴을 제공합니다. 이러한 리소스는 AWS 기술 전문가와 글로벌 AWS 파트너 커뮤니티가 고객의 비즈니스 목표 달성을 지원한 다년간의 경험을 바탕으로 개발했습니다.

**데이터 모델링 및 마이그레이션**
+ [DynamoDB의 계층적 데이터 모델](https://docs.aws.amazon.com/prescriptive-guidance/latest/dynamodb-hierarchical-data-model/introduction.html)
+ [DynamoDB를 사용한 데이터 모델링](https://docs.aws.amazon.com/prescriptive-guidance/latest/dynamodb-data-modeling/welcome.html)
+ [를 사용하여 DynamoDB로 Oracle 데이터베이스 마이그레이션AWS DMS](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/migrate-an-oracle-database-to-amazon-dynamodb-using-aws-dms.html)

**글로벌 테이블**
+ [Amazon DynamoDB 글로벌 테이블 사용](https://docs.aws.amazon.com/prescriptive-guidance/latest/dynamodb-global-tables/introduction.html)

**서버리스**
+ [를 사용하여 서버리스 사가 패턴 구현AWS Step Functions](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/implement-the-serverless-saga-pattern-by-using-aws-step-functions.html)

**SaaS 아키텍처**
+ [단일 컨트롤 플레인에서 여러 SaaS 제품의 테넌트 관리](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/manage-tenants-across-multiple-saas-products-on-a-single-control-plane.html)
+ [C\$1 및 AWS CDK를 사용한 사일로 모델을 위한 SaaS 아키텍처의 테넌트 온보딩](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.html)

**데이터 보호 및 데이터 이동**
+ [Amazon DynamoDB에 대한 크로스 계정 액세스 구성](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/configure-cross-account-access-to-amazon-dynamodb.html)
+ [DynamoDB의 전체 테이블 복사 옵션](https://docs.aws.amazon.com/prescriptive-guidance/latest/dynamodb-full-table-copy-options/)
+ [의 데이터베이스에 대한 재해 복구 전략AWS](https://docs.aws.amazon.com/prescriptive-guidance/latest/strategy-database-disaster-recovery/)

**기타사항**
+ [DynamoDB에서 태깅 적용 지원](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/help-enforce-dynamodb-tagging.html)

**권장 가이드 비디오 둘러보기**
+ [서버리스 아키텍처를 사용한 데이터 파이프라인 생성](https://youtu.be/JiWHomdh1oI?)
+ [Novartis - 구매 엔진: AI 기반 조달 포털](https://youtu.be/vp8oPiHN4cA)
+ [Veritiv: AWS 데이터 레이크에서 인사이트를 활용하여 판매 수요 예측](https://youtu.be/jg85DzUZ9Ac)
+ [mimik: AWS를 활용하는 하이브리드 엣지 클라우드로 엣지 마이크로서비스 메시 지원](https://youtu.be/-S-R7MWRpaI)
+ [Amazon DynamoDB를 사용하여 변경 데이터 캡처](https://youtu.be/6YVjzD-70p4)

DynamoDB에 대한 추가 권장 가이드 문서 및 비디오는 [권장 가이드](https://tiny.amazon.com/fiui3cog/ForinternaldemoofnewpageExternalURLwillbeneededforlive)를 참조하세요.

## 지식 센터 문서
<a name="AdditionalResources.KnowledgeCenter"></a>

AWS 지식 센터 문서 및 비디오에는 AWS 고객으로부터 가장 자주 받는 질문과 요청이 수록되어 있습니다. 다음은 DynamoDB와 관련된 특정 작업에 대한 최신 지식 센터 문서입니다.

**비용 최적화**.
+ [Amazon DynamoDB로 비용을 최적화하려면 어떻게 해야 하나요?](https://repost.aws/knowledge-center/dynamodb-optimize-costs)

**제한 및 지연 시간**
+ [Amazon DynamoDB 테이블에서 지연 시간이 긴 문제를 해결하려면 어떻게 해야 하나요?](https://repost.aws/knowledge-center/dynamodb-high-latency)
+ [DynamoDB 테이블이 제한되는 이유는 무엇인가요?](https://repost.aws/knowledge-center/dynamodb-table-throttled)
+ [온디맨드 DynamoDB 테이블이 제한되는 이유는 무엇인가요?](https://repost.aws/knowledge-center/on-demand-table-throttling-dynamodb)

**페이지 매김**
+ [DynamoDB에서 페이지 매김을 구현하려면 어떻게 해야 하나요](https://repost.aws/knowledge-center/dynamodb-implement-pagination)

**트랜잭션**
+ [DynamoDB에서 `TransactWriteItems` API 호출이 실패하는 이유는 무엇인가요?](https://repost.aws/knowledge-center/dynamodb-transactwriteitems)

**문제 해결** - 

[]()
+ [DynamoDB Auto Scaling 문제를 해결하려면 어떻게 해야 하나요?](https://repost.aws/knowledge-center/dynamodb-auto-scaling)
+ [DynamoDB에서 HTTP 4XX 오류를 해결하려면 어떻게 해야 하나요](https://repost.aws/knowledge-center/usererrors-dynamodb-table)

DynamoDB에 대한 추가 문서 및 비디오는 [지식 센터 문서](https://repost.aws/search/knowledge-center?globalSearch=dynamodb)를 참조하세요.

## 블로그 게시물, 리포지토리 및 가이드
<a name="AdditionalResources.Guides"></a>

[DynamoDB 개발자 안내서](Introduction.md) 외에도 DynamoDB를 사용하는 데 유용한 리소스가 많이 있습니다. 다음은 DynamoDB 작업에 필요한 몇 가지 엄선된 블로그 게시물, 리포지토리 및 가이드입니다.
+ 다양한 AWS SDK 언어([Node.js,](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/node.js) [Java,](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/java) [Python](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/python) [.NET,](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/dotnet) [Go,](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/golang), [Rust](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/rust))로 지원되는 AWS의 [DynamoDB 코드 예제](https://github.com/aws-samples/aws-dynamodb-examples) 리포지토리입니다.
+ [DynamoDB 북](https://www.dynamodbbook.com/) - [Alex DeBrie](https://twitter.com/alexbdebrie)의 종합 가이드로, DynamoDB를 사용한 데이터 모델링에 대한 전략 중심의 접근 방식을 소개합니다.
+ [DynamoDB 가이드](https://www.dynamodbguide.com/) - [Alex DeBrie](https://twitter.com/alexbdebrie)의 오픈 가이드로, DynamoDB NoSQL 데이터베이스의 기본 개념과 고급 기능을 살펴봅니다.
+ [20가지 간단한 단계를 통해 RDBMS에서 DynamoDB로 전환하는 방법](https://www.jeremydaly.com/how-to-switch-from-rdbms-to-dynamodb-in-20-easy-steps/) - [Jeremy Daly](https://twitter.com/jeremy_daly)가 제공하는 데이터 모델링 학습에 유용한 단계 목록입니다.
+ [DynamoDB JavaScript DocumentClient 치트 시트](https://github.com/dabit3/dynamodb-documentclient-cheat-sheet) - Node.js 또는 JavaScript 환경에서 DynamoDB를 사용하여 애플리케이션 빌드를 시작하는 데 도움이 되는 치트 시트입니다.
+ [DynamoDB 핵심 개념 비디오](https://www.youtube.com/playlist?list=PLJo-rJlep0EDNtcDeHDMqsXJcuKMcrC5F) - 이 재생 목록은 DynamoDB의 여러 핵심 개념을 다룹니다.

## 데이터 모델링 및 디자인 패턴 프레젠테이션
<a name="AdditionalResources.DataModeling"></a>

DynamoDB를 최대한 효과적으로 활용하는 데 도움이 되는 데이터 모델링 및 디자인 패턴에 대한 다음 리소스를 사용할 수 있습니다.
+ [AWS re:Invent 2019: DynamoDB를 활용한 데이터 모델링](https://www.youtube.com/watch?v=DIQVJqiSUkE) 
  + DynamoDB 데이터 모델링의 원칙을 안내하는 [Alex DeBrie](https://twitter.com/alexbdebrie)의 강연입니다.
+ [AWS re:Invent 2020: DynamoDB를 활용한 데이터 모델링 - 1부](https://www.youtube.com/watch?v=fiP2e-g-r4g)
+ [AWS re:Invent 2020: DynamoDB를 활용한 데이터 모델링 - 2부](https://www.youtube.com/watch?v=0uLF1tjI_BI)
+ [AWS re:Invent 2017: 고급 디자인 패턴](https://www.youtube.com/watch?v=jzeKPKpucS0)
+ [AWS re:Invent 2018: 고급 디자인 패턴](https://www.youtube.com/watch?v=HaEPXoXVf2k)
+ [AWS re:Invent 2019: 고급 디자인 패턴](https://www.youtube.com/watch?v=6yqfmXiZTlM)
  + 이 세션에서 Jeremy Daly가 자신의 [12가지 핵심 고려 사항](https://www.jeremydaly.com/takeaways-from-dynamodb-deep-dive-advanced-design-patterns-dat403/)을 공유합니다.
+ [AWS re:Invent 2020: DynamoDB 고급 디자인 패턴 - 1부](https://www.youtube.com/watch?v=MF9a1UNOAQo&index=1)
+ [AWS re:Invent 2020: DynamoDB 고급 디자인 패턴 - 2부](https://www.youtube.com/watch?v=_KNrRdWD25M&index=2)
+ [Twitch의 DynamoDB 오피스 아워](https://amazondynamodbofficehrs.splashthat.com/)

**참고**  
각 세션에서는 다양한 사용 사례와 예제를 다룹니다.

## 교육 과정
<a name="AdditionalResources.Training"></a>

DynamoDB에 대해 자세히 알아볼 수 있는 다양한 교육 과정과 교육 옵션이 있습니다. 다음은 몇 가지 최신 예입니다.
+ [Amazon DynamoDB를 활용한 개발](https://www.aws.training/Details/Curriculum?id=65583) - AWS에서 설계한 과정으로, Amazon DynamoDB용 데이터 모델링을 통해 실제 애플리케이션을 개발하는 초보자에서 전문가까지 안내해드립니다.
+ [DynamoDB 심층 분석 과정](https://www.pluralsight.com/courses/aws-dynamodb-deep-dive-2019) - Pluralsight의 교육 과정입니다.
+ [Amazon DynamoDB: NoSQL 데이터베이스 중심 애플리케이션 빌드](https://www.edx.org/course/amazon-dynamodb-building-nosql-database-driven-app) - edX에서 호스팅되는 AWS 교육 및 자격증 팀의 교육 과정입니다.