

 Amazon Redshift は、パッチ 198 以降、新しい Python UDF の作成をサポートしなくなります。既存の Python UDF は、2026 年 6 月 30 日まで引き続き機能します。詳細については、[ブログ記事](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)を参照してください。

# Amazon Redshift でのデータのロード
<a name="t_Loading_data"></a>

Amazon Redshift データベースにデータをロードするには、いくつかの方法があります。データのロード元として一般的なソースの 1 つは、Amazon S3 ファイルです。次の表は、Amazon S3 ソースから開始する場合に使用するいくつかの方法を示しています。


| 使用する方法 | 説明 | 方法が必要になる場合 | 
| --- | --- | --- | 
| COPY コマンド | バッチファイルの取り込みを実行して、Amazon S3 ファイルからデータをロードします。この方法では、Amazon Redshift の並列処理機能を活用します。詳細については、「[COPY コマンドを使ってテーブルをロードする](t_Loading_tables_with_the_COPY_command.md)」を参照してください。 | バッチファイルの取り込みを手動で開始するための基本的なデータロード要件が必要な場合に使用します。この方法は、主にカスタムおよびサードパーティのファイル取り込みパイプラインで使用するか、1 回限りまたはアドホックのファイル取り込みワークロードで使用します。 | 
| COPY... CREATE JOB コマンド (自動コピー） | 追跡中の Amazon S3 パスで新しいファイルを作成すると、COPY コマンドが自動的に実行されます。詳細については、「[S3 イベント統合を作成して Amazon S3 バケットからファイルを自動的にコピーする](loading-data-copy-job.md)」を参照してください。 | Amazon S3 で新しいファイルを作成するときに、ファイル取り込みパイプラインでデータを自動的に取り込む必要がある場合に使用します。Amazon Redshift は、データの重複を防ぐために、取り込んだファイルを追跡し続けます。この方法では、Amazon S3 バケット所有者による設定が必要です。 | 
| データレイククエリからのロード | 外部テーブルを作成して Amazon S3 ファイルに対してデータレイククエリを実行し、INSERT INTO コマンドを実行してデータレイククエリの結果をローカルテーブル内にロードします。詳細については、「[Redshift Spectrum 用の外部テーブル](c-spectrum-external-tables.md)」を参照してください。 | 次のいずれかのシナリオで使用します。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/t_Loading_data.html) | 
| その他の検討可能な方法 | 
| ストリーミング取り込み  | ストリーミング取り込みでは、Amazon Kinesis Data Streams や Amazon Managed Streaming for Apache Kafka から、Amazon Redshift でプロビジョニングされたビューや Redshift Serverless マテリアライズドビューに、ストリームデータを低レイテンシーかつ高速で取り込むことができます。詳細については、「[Amazon Kinesis Data Streams からストリーミング取り込みを開始する方法](materialized-view-streaming-ingestion-getting-started.md)」および「[Apache Kafka ソースからのストリーミング取り込みの開始方法](materialized-view-streaming-ingestion-getting-started-MSK.md)」を参照してください。 | データを最初に Amazon S3 のファイルにストリーミングし、次に Amazon S3 からロードする場合のユースケースで検討します。Amazon S3 にデータを保持する必要がない場合は、通常、データを Amazon Redshift 内に直接ストリーミングすることを検討できます。 | 
| データレイククエリの実行 | テーブルの内容をローカルテーブルに取り込む代わりに、データレイクテーブルから直接クエリを実行します。詳細については、「[Amazon Redshift Spectrum](c-using-spectrum.md)」を参照してください。 | Amazon Redshift でのローカルテーブルクエリのパフォーマンスを必要としないユースケースで使用します。 | 
| Amazon Redshift クエリエディタ v2 を使用したバッチロード | Amazon Redshift クエリエディタ v2 で、バッチファイル取り込みワークロードを視覚的に準備して実行できます。詳細については、「Amazon Redshift 管理ガイド」の「[S3 からデータをロードする](https://docs.aws.amazon.com/redshift/latest/mgmt/query-editor-v2-loading.html#query-editor-v2-loading-data)」を参照してください。** | クエリエディタ v2 で COPY ステートメントを準備する場合、COPY ステートメントの準備プロセスを簡素化するビジュアルツールが必要なときに使用します。 | 
| Amazon Redshift クエリエディタ v2 を使用したローカルファイルからのデータのロード | デスクトップから Amazon Redshift テーブルにファイルを直接アップロードできます。Amazon S3 にファイルを手動でアップロードする必要はありません。詳細については、「Amazon Redshift 管理ガイド」の「[ローカルファイル設定とワークフローからのデータのロード](https://docs.aws.amazon.com/redshift/latest/mgmt/query-editor-v2-loading.html#query-editor-v2-loading-data-local)」を参照してください。** | 1 回限りのクエリのためにローカルコンピュータからファイルをすばやくロードする必要がある場合に使用します。この方法の場合、Amazon Redshift クエリエディタ v2 は、お客様所有の Amazon S3 バケットにファイルを一時的に保存し、この Amazon S3 パスを使用してコピーコマンドを実行します。 | 

COPY コマンドは、テーブルをロードする最も効率的な方法です。INSERT コマンドを使ってデータをテーブルに追加することもできます。ただし、COPY コマンドを使ったほうが効率的です。COPY コマンドは、複数のデータファイルまたは複数のデータストリームから同時に読み込むことができます。Amazon Redshift はワークロードを Amazon Redshift ノードに割り当て、ノードスライス間での行のソートやデータの分散など、ロードオペレーションを並列で実行します。

**注記**  
Amazon Redshift Spectrum の外部テーブルは読み込み専用です。外部テーブルには COPY または INSERT できません。

Amazon Redshift が他の AWS リソースのデータにアクセスするには、これらのリソースにアクセスして必要なアクションを実行するためのアクセス許可が必要です。AWS Identity and Access Management (IAM) を使用すると、Amazon Redshift のリソースとデータに対するユーザーのアクセスを制限できます。

初回のデータロードの後、大量のデータを追加、変更、削除した場合、VACUUM コマンドを実行してデータを再編成し、削除後の領域を利用可能な状態に戻してください。また、ANALYZE コマンドを実行し、テーブル統計を更新します。

**Topics**
+ [COPY コマンドを使ってテーブルをロードする](t_Loading_tables_with_the_COPY_command.md)
+ [S3 イベント統合を作成して Amazon S3 バケットからファイルを自動的にコピーする](loading-data-copy-job.md)
+ [DML コマンドによるテーブルのロード](t_Updating_tables_with_DML_commands.md)
+ [ディープコピーを実行する](performing-a-deep-copy.md)
+ [テーブルを分析する](t_Analyzing_tables.md)
+ [テーブルのバキューム処理](t_Reclaiming_storage_space202.md)
+ [同時書き込み操作を管理する](c_Concurrent_writes.md)
+ [チュートリアル: Amazon S3 からデータをロードする](tutorial-loading-data.md)

# COPY コマンドを使ってテーブルをロードする
<a name="t_Loading_tables_with_the_COPY_command"></a>

COPY コマンドは Amazon Redshift の超並列処理 (MPP) アーキテクチャを活用し、Amazon S3 のファイル、DynamoDB テーブル、リモートホストから出力されたテキストのいずれかから並列でデータをロードします。

COPY コマンドのすべてのオプションを学習する前に、Amazon S3 データをロードするための基本的なオプションを学習することをお勧めします。「Amazon Redshift 入門ガイド」は、デフォルトの IAM ロールを使用して Amazon S3 データをロードするための COPY コマンドの簡単な使用方法を示しています。**詳細については、「[ステップ 4: Amazon S3 から Amazon Redshift にデータをロードする](https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-create-sample-db.html)」を参照してください。

**注記**  
大量のデータをロードする場合、COPY コマンドを使うことをお勧めします。個々に INSERT ステートメントを使ってテーブルにデータを入力すると著しく時間がかかる場合があります。または、他の Amazon Redshift データベーステーブルにデータが既に存在する場合、パフォーマンスを向上させるには INSERT INTO ... SELECT または CREATE TABLE AS を使用します。詳細については、「[INSERT](r_INSERT_30.md)」または「[CREATE TABLE AS](r_CREATE_TABLE_AS.md)」を参照してください。

Amazon Redshift で別の AWS リソースからデータをロードするには、リソースにアクセスして必要なアクションを実行するためのアクセス許可が必要です。

COPY コマンドを使ってデータをテーブルにロードするための権限を与えるか、取り消すには、INSERT 権限を与えるか、取り消します。

データを Amazon Redshift テーブルにロードするために、適切な形式にする必要があります。このセクションでは、ロードする前のデータを準備し確認するための指針、ならびに実行する前の COPY ステートメントを検証するための指針を紹介します。

Amazon S3 バケットにアップロードするデータファイルの情報を保護するには、事前に暗号化しておきます。COPY を実行すると、ロード時にデータが復号されます。一時的セキュリティ認証情報をユーザーに与えることで、データロードのアクセスを制限することもできます。一時的セキュリティ認証情報はセキュリティを強化します。使用期限が短く、期限が切れた後は再利用できないためです。

Amazon Redshift には、区切られた非圧縮データをすばやくロードするための COPY 機能が組み込まれています。加えて、gzip、lzop、bzip2 のいずれかによりファイルを圧縮することで、そのファイルのアップロードにかかる時間を短縮できます。

COPY クエリに ESCAPE、REMOVEQUOTES、および FIXEDWIDTH のキーワードが含まれる場合、非圧縮データの自動分割はサポートされませんが、CSV キーワードの場合はサポートされます。

Amazon Redshift では、AWS クラウド内で転送されるデータのセキュリティを確保するために、COPY、UNLOAD、バックアップ、復旧オペレーションの実行時の Amazon S3 または Amazon DynamoDB との通信に、ハードウェアでアクセラレーションされた SSL を使用します。

Amazon DynamoDB テーブルからデータを直接ロードするとき、Amazon DynamoDB がプロビジョニングするスループットの消費量を制御するオプションがあります。

任意で COPY を使い、入力データを分析したり、ロードプロセスの一部として最適な圧縮エンコーディングをテーブルに自動的に適用したりできます。

**Topics**
+ [認証情報とアクセス許可](loading-data-access-permissions.md)
+ [入力データを準備する](t_preparing-input-data.md)
+ [Amazon S3 からデータをロードする](t_Loading-data-from-S3.md)
+ [Amazon EMR からのデータのロード](loading-data-from-emr.md)
+ [リモートホストからデータをロードする](loading-data-from-remote-hosts.md)
+ [Amazon DynamoDB テーブルからのデータのロード](t_Loading-data-from-dynamodb.md)
+ [データが正しくロードされたことを確認する](verifying-that-data-loaded-correctly.md)
+ [入力データを検証する](t_Validating_input_files.md)
+ [自動圧縮ありでテーブルをロードする](c_Loading_tables_auto_compress.md)
+ [細長いテーブルのストレージの最適化](c_load_compression_hidden_cols.md)
+ [デフォルトの列値をロードする](c_loading_default_values.md)
+ [データロードのトラブルシューティング](t_Troubleshooting_load_errors.md)

# 認証情報とアクセス許可
<a name="loading-data-access-permissions"></a>

 Amazon S3、Amazon DynamoDB、Amazon EMR、Amazon EC2 など、別の AWS リソースを Amazon Redshift で使用してデータをロードまたはアンロードするには、リソースにアクセスし、必要なアクションを実行してデータを利用するためのアクセス許可が必要です。例えば、Amazon S3 からデータをロードする場合、COPY はバケットへの LIST アクセスとバケットオブジェクトへの GET アクセスが必要です。

リソースへのアクセス認可を取得するには、Amazon Redshift の認証が必要です。ロールベースのアクセスコントロールまたはキーに基づくアクセスコントロールのいずれかを選択できます。このセクションは 2 つの方法の概要を示します。詳細と例については、[他の AWS リソースにアクセスするアクセス許可](copy-usage_notes-access-permissions.md) を参照してください。

## ロールベースアクセスコントロール
<a name="loading-data-access-role-based"></a>

ロールベースのアクセスコントロールを使用する場合、Amazon Redshift はユーザーに代わって AWS Identity and Access Management (IAM) ロールを一時的に引き受けます。次に、ロールに付与された許可に応じて、Amazon Redshift は必要な AWS リソースにアクセスできます。

ロールベースのアクセスコントロールの利用をお勧めします。これにより、AWS 認証情報が保護されるだけでなく、AWS のリソースと機密性のあるユーザーデータに対するアクセスがより安全になり、きめ細やかなコントロールが行われます。

ロールベースのアクセスコントロールを使用するには、まず Amazon Redshift サービスロールタイプを使用して IAM ロールを作成し、次にロールをデータウェアハウスにアタッチする必要があります。ロールは、少なくとも [COPY、UNLOAD、CREATE LIBRARY のための IAM のアクセス許可](copy-usage_notes-access-permissions.md#copy-usage_notes-iam-permissions) に示されたアクセス権限が必要です。IAM ロールを作成してクラスターにアタッチする手順については、「*Amazon Redshift 管理ガイド*」の「[Amazon Redshift クラスターによって AWS のサービスへのアクセスを許可する IAM ロールを作成する](https://docs.aws.amazon.com/redshift/latest/mgmt/authorizing-redshift-service.html#authorizing-redshift-service-creating-an-iam-role)」を参照してください。

クラスターにロールを追加するか、Amazon Redshift マネジメントコンソール、CLI、または API を使用してクラスターに関連付けられるロールを表示できます。詳細については、「*Amazon Redshift 管理ガイド*」の「[IAM ロールを使用した COPY および UNLOAD オペレーションの認可](https://docs.aws.amazon.com/redshift/latest/mgmt/copy-unload-iam-role.html)」を参照してください。

IAM ロールを作成する場合、IAM はロールの Amazon リソースネーム (ARN) を返します。IAM ロールを使用して COPY コマンドを実行するには、IAM\$1ROLE パラメータまたは CREDENTIALS パラメータを介してロールの ARN を指定します。

次の COPY コマンドの例では、ロール `MyRedshiftRole` を指定した IAM\$1ROLE パラメータを認証に使用します。

```
COPY customer FROM 's3://amzn-s3-demo-bucket/mydata' 
IAM_ROLE 'arn:aws:iam::12345678901:role/MyRedshiftRole';
```

AWS ユーザーは、少なくとも [COPY、UNLOAD、CREATE LIBRARY のための IAM のアクセス許可](copy-usage_notes-access-permissions.md#copy-usage_notes-iam-permissions) に示されたアクセス許可が必要です。

## キーベースのアクセスコントロール
<a name="loading-data-access-key-based"></a>

キーベースのアクセスコントロールでは、データがある AWS リソースへのアクセスを許可されたユーザーのアクセスキー ID とシークレットアクセスキーを指定します。 

**注記**  
プレーンテキストのアクセスキー ID とシークレットアクセスキーを指定する代わりに、認証のために IAM ロールを使用することを強くお勧めします。キーベースのアクセスコントロールを選択する場合は、AWSアカウント (ルート) 認証情報を使用しないでください。常に IAM ユーザーを作成し、そのユーザーのアクセスキー ID とシークレットアクセスキーを指定します。IAM ユーザーを作成する手順については、「[AWS アカウントでの IAM ユーザーの作成](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)」を参照してください。

# 入力データを準備する
<a name="t_preparing-input-data"></a>

入力データとそれを受け取るテーブル列の間に互換性がない場合、COPY コマンドは失敗します。

次の指針を利用し、入力データの妥当性を確認してください。
+ データには最大 4 バイトの UTF-8 文字のみを含めることができます。
+ CHAR 文字列と VARCHAR 文字列がそれに対応する列の長さを超えないことを確認してください。VARCHAR 文字列は文字数ではなく、バイト数でカウントされます。そのため、例えば、4 バイトを使う漢字が 4 文字集まった文字列は VARCHAR(16) 列を必要とします。
+ マルチバイト文字は VARCHAR 列との連動でのみ使用できます。マルチバイト文字が 4 バイトを超えないことを確認します。
+ CHAR 列のデータにシングルバイトの文字のみが含まれることを確認します。
+ レコードの最後のフィールドを示すために特殊な文字や構文を含めないでください。このフィールドは区切り文字にすることができます。
+ NUL (UTF-8 0000) またはバイナリゼロ (0x000) とも呼ばれる null ターミネーターをデータに含める場合、これらの文字は NULLS として CHAR 列または VARCHAR 列にロードすることができます。その際、COPY コマンドでは NULL AS オプションを使用します (`null as '\0'` または `null as '\000'`)。NULL AS を使用しない場合、null ターミネーターが原因となり、COPY が失敗します。
+ 文字列に、区切り文字や埋め込み改行など、特殊文字が含まれる場合、[COPY](r_COPY.md) コマンドとともに ESCAPE オプションを使用します。
+ 一重引用符と二重引用符がすべて適切に一致していることを確認してください。
+ 浮動小数点の文字列が 12.123 のような標準浮動小数点形式と 1.0E4 のような指数形式のいずれかになっていることを確認してください。
+ すべてのタイムスタンプおよび日付文字列が [DATEFORMAT と TIMEFORMAT の文字列例](r_DATEFORMAT_and_TIMEFORMAT_strings.md) の仕様に従っていることを確認してください。デフォルトのタイムスタンプ形式は YYYY-MM-DD hh:mm:ss であり、デフォルトの日付形式は YYYY-MM-DD です。
+ 個々のデータ型の制約に関する詳細は、「[データ型](c_Supported_data_types.md)」を参照してください。マルチバイト文字のエラーに関する詳細は、「[マルチバイト文字のロードエラー](multi-byte-character-load-errors.md)」を参照してください。

# Amazon S3 からデータをロードする
<a name="t_Loading-data-from-S3"></a>

COPY コマンドは Amazon Redshift の超並列処理 (MPP) アーキテクチャを利用し、Amazon S3 バケット内の単一もしくは複数のファイルとの間で、データの読み取りやロードを並列的に実行します。ファイルが圧縮されている場合は、データを複数のファイルに分割することで、並列処理の長所を最大限に活用できます。(このルールには例外があります。詳細については、「[データファイルのロード](https://docs.aws.amazon.com/redshift/latest/dg/c_best-practices-use-multiple-files.html)」を参照してください。) また、テーブルで分散キーを設定することによっても、並列処理の長所を最大化できます。分散キーの詳細については、「[クエリ最適化のためのデータのディストリビューション](t_Distributing_data.md)」を参照してください。

データは、ターゲットテーブルの各行に 1 行が対応するようにロードされます。データファイルのフィールドは左から右の順でテーブル列に一致します。データファイルのフィールドは固定幅か文字区切りになります。デフォルトの区切り文字はパイプ (\$1) です。デフォルトでは、すべてのテーブル列がロードされますが、任意の列のリストをカンマ区切りで指定することもできます。COPY コマンドに指定された列リストに含まれていない列については、デフォルト値がロードされます。詳細については、「[デフォルトの列値をロードする](c_loading_default_values.md)」を参照してください。

**Topics**
+ [圧縮および非圧縮のファイルからのデータのロード](t_splitting-data-files.md)
+ [Amazon S3 にファイルをアップロードして COPY で使用する](t_uploading-data-to-S3.md)
+ [COPY コマンドを使用し、Amazon S3 からロードする](t_loading-tables-from-s3.md)

# 圧縮および非圧縮のファイルからのデータのロード
<a name="t_splitting-data-files"></a>

圧縮データをロードする際には、データを、各テーブルに対応させ複数のファイルに分割することをお勧めします。Amazon S3 バケット内の大きなファイルから区切りのある非圧縮データをロードする場合、COPY コマンドは、そのデータのロードに超並列処理 (MPP) とスキャン範囲を使用します。

## 複数の圧縮されたファイルからのデータのロード
<a name="t_splitting-data-files-compressed"></a>

データが圧縮されている場合は、各テーブル用に複数のファイルとして、データを分割することをお勧めします。COPY コマンドを実行すると、複数のファイルから並列でデータをロードすることができます。セットに共通プレフィックスまたは*プレフィックスキー*を指定するか、マニフェストファイルにファイルのリストを明示的に指定することで、複数のファイルをロードできます。

ファイルの数がクラスターのスライスの数の倍数になるようにデータをファイルに分割します。これにより、Amazon Redshift は各スライス間でデータを均等に分割できます。ノードあたりのスライスの数は、クラスターのノードサイズによって決まります。例えば、各 dc2.large コンピューティングノードには 2 個のスライスがあり、各 dc2.8xlarge コンピューティングノードには 16 個のスライスがあります。各ノードサイズに含まれるスライス数の詳細については、「*Amazon Redshift 管理ガイド*」の「[クラスターおよびノードについて](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-about-clusters-and-nodes)」を参照してください。

ノードはいずれも並列クエリの実行に関与し、スライス全体でできるだけ均等に分散されたデータを処理します。クラスターに dc2.large ノードが 2 つある場合は、データを 4 つのファイルまたは 4 の倍数のファイルに分割できます。Amazon Redshift はワークロードを分割するときにファイルサイズを考慮しません。したがって、圧縮後の各ファイルは、ほぼ同じ (1 MB～1 GB の間の) サイズにする必要があります。

オブジェクトプレフィックスを使ってロード対象のファイルを識別する場合、各ファイルの名前に共通のプレフィックスを付けます。例えば、`venue.txt` ファイルを下記のように 4 つのファイルに分割します。

```
venue.txt.1
venue.txt.2
venue.txt.3
venue.txt.4
```

複数のファイルをバケットのフォルダーに置いている場合、プレフィックスとしてフォルダー名を指定すると、COPY によりフォルダー内のすべてのファイルがロードされます。ロードするファイルが複数のバケットまたはフォルダーに分散している場合は、それらのファイルのリストをマニフェストファイルに明示的に指定します。

マニフェストファイルについて詳しくは、「[マニフェストを使用し、データファイルを指定する](r_COPY_command_examples.md#copy-command-examples-manifest)」を参照してください。

## 非圧縮の区切りファイルからのデータの読み込み
<a name="t_splitting-data-files-uncompressed"></a>

区切りのある非圧縮データをロードする際、COPY コマンドは Amazon Redshift の超並列処理 (MPP) アーキテクチャを使用します。Amazon Redshift は、各スライスを自動的に並列処理し、それぞれに応じた範囲のデータを、Amazon S3 バケット内の大きなファイルからロードします。並列ロードを実行するには、ファイルを区切る必要があります。例えば、パイプ区切りなどを使用します。CSV ファイルでは、COPY コマンドでの自動的な並列データロードも利用できます。テーブルに分散キーを設定することによって並列処理を活用することも可能です。分散キーの詳細については、「[クエリ最適化のためのデータのディストリビューション](t_Distributing_data.md)」を参照してください。

COPY クエリに ESCAPE、REMOVEQUOTES、および FIXEDWIDTH キーワードのどれかが含まれている場合、自動的な並列データロードはサポートされません。

単一もしくは複数のファイルからのデータは、ターゲットテーブルの各行ごとに 1 行が対応してロードされます。データファイルのフィールドは左から右の順でテーブル列に一致します。データファイルのフィールドは固定幅か文字区切りになります。デフォルトの区切り文字はパイプ (\$1) です。デフォルトでは、すべてのテーブル列がロードされますが、任意の列のリストをカンマ区切りで指定することもできます。テーブルの列が COPY コマンドで指定された列リストに含まれていない場合は、デフォルト値を使用してロードされます。詳細については、「[デフォルトの列値をロードする](c_loading_default_values.md)」を参照してください。

Amazon S3 から区切りのある非圧縮なデータをロードする場合は、次の一般的なプロセスに従います。

1. ファイルを Amazon S3 にアップロードします。

1. COPY コマンドを実行し、テーブルをロードします。

1. データが正しくロードされたことを確認します。

COPY コマンドの例については、「[COPY の例](r_COPY_command_examples.md)」を参照してください。Amazon Redshift にロードされたデータに関する情報は、システムテーブル [STL\$1LOAD\$1COMMITS](r_STL_LOAD_COMMITS.md) および [STL\$1LOAD\$1ERRORS](r_STL_LOAD_ERRORS.md) でご確認ください。

これらに含まれるノードとスライスの詳細については、「*Amazon Redshift 管理ガイド*」の「[クラスターおよびノードについて](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-about-clusters-and-nodes)」を参照してください。

# Amazon S3 にファイルをアップロードして COPY で使用する
<a name="t_uploading-data-to-S3"></a>

Amazon S3 にテキストファイルをアップロードする場合には、以下のように、取るべきいくつかのアプローチがあります。
+ ファイルが大規模で圧縮されている場合は、Amazon Redshift の並列処理を活用するために、そのファイルを分割することをお勧めします。
+ また COPY では、大きな圧縮されていないテキスト区切りファイルの場合にデータは自動で分割されるので、これにより並列処理が容易になり、大きなファイルからのデータ配布が効果的に行われます。

データファイルを入れる Amazon S3 バケットを作成し、データファイルをバケットにアップロードします。バケットの作成およびファイルのアップロードの詳細については、*Amazon Simple Storage Service ユーザーガイド*の[Amazon S3 バケットの操作](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html)を参照してください。

**重要**  
[REGION](copy-parameters-data-source-s3.md#copy-region) オプションを使用して Amazon S3 バケットがあるリージョンを指定しない限り、データファイルを保持する Amazon S3 バケットは、クラスターと同じ AWS リージョンに作成する必要があります。

S3 IP 範囲が許可リストに追加されていることを確認します。必要な S3 IP 範囲の詳細については、「[ネットワークの隔離](https://docs.aws.amazon.com//redshift/latest/mgmt/security-network-isolation.html#network-isolation)」を参照してください。

Amazon S3 コンソールを利用してバケットを作成するときにリージョンを選択するか、Amazon S3 API または CLI を利用してバケットを作成するときにエンドポイントを指定することで、特定のリージョンに Amazon S3 バケットを作成できます。

データのロード後、Amazon S3 に正しいファイルが存在することを確認します。

**Topics**
+ [データの整合性の管理](managing-data-consistency.md)
+ [Amazon S3 への暗号化されたデータのアップロード](t_uploading-encrypted-data.md)
+ [必要なファイルがバケットにあることを確認する](verifying-that-correct-files-are-present.md)

# データの整合性の管理
<a name="managing-data-consistency"></a>

Amazon S3 では、すべての AWS リージョンにある Amazon S3 バケットに対する COPY、UNLOAD、INSERT (外部テーブル)、CREATE EXTERL TABLE AS、および Amazon Redshift Spectrum オペレーションについて、書き込みとそれに続く読み込みの間での、強力な一貫性が提供されます。さらに、Amazon S3 Select、Amazon S3 アクセスコントロールリスト、Amazon S3 オブジェクトタグ、オブジェクトメタデータ (HEAD オブジェクトなど) での読み込みオペレーションには、強力な整合性があります。データ整合性の詳細については、*Amazon Simple Storage Service デベロッパーガイド*の[ Amazon S3 のデータ整合性モデル](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Introduction.html#ConsistencyModel)を参照してください。

# Amazon S3 への暗号化されたデータのアップロード
<a name="t_uploading-encrypted-data"></a>

Amazon S3 は、サーバー側の暗号化とクライアント側の暗号化のどちらもサポートします。このトピックでは、サーバー側暗号化とクライアント側暗号化の違いを説明し、Amazon Redshift でクライアント側暗号化を使用するステップを紹介します。サーバー側暗号化は Amazon Redshift に対して透過的です。

## サーバー側の暗号化
<a name="server-side-encryption"></a>

サーバー側の暗号化は、保管時のデータ暗号化です。つまり、Amazon S3 がデータをアップロードするときにデータを暗号化し、アクセス時にデータを復号化します。COPY コマンドを使用してテーブルをロードする場合には、Amazon S3 にあるサーバー側で暗号化したオブジェクトや暗号化していないオブジェクトからロードする場合との間に差はありません。サーバー側の暗号化の詳細については、*Amazon Simple Storage Service ユーザーガイド*の[サーバー側の暗号化の使用](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingServerSideEncryption.html)を参照してください。

## クライアント側の暗号化
<a name="client-side-encryption"></a>

クライアント側の暗号化の場合、データの暗号化、暗号化キー、および関連ツールを管理するのはクライアントアプリケーションです。クライアント側の暗号化を使って Amazon S3 バケットにデータをアップロードし、その後、COPY コマンド (ENCRYPTED オプション) とプライベート暗号化キーを使ってデータをより安全にロードすることができます。

エンベロープ暗号化を使い、データを暗号化します。*エンベロープ暗号化*を使うと、アプリケーションですべての暗号化が排他的に処理されます。プライベート暗号化キーと暗号化されていないデータが AWS に送信されることはありません。したがって、暗号化キーを安全に管理することが重要となります。暗号化キーをなくした場合はデータを復号できなくなります。また、AWS から暗号化キーを復元することはできません。エンベロープ暗号化では、非同期キーによるキー管理によりセキュリティを高めながら、高速の同期暗号化のパフォーマンスを実現します。Amazon S3 暗号化クライアントは、データを暗号化するためにワンタイム使用の対称キー (エンベロープ対称キー) を生成します。その後、そのキーはルートキーにより暗号化され、データとともに Amazon S3 に保存されます。Amazon Redshift がロード時にデータにアクセスするとき、暗号化された同期キーが取得され、本物のキーで復号され、その後、データが復号されます。

Amazon Redshift で Amazon S3 クライアント側の暗号化データを操作するには、*Amazon Simple Storage Service ユーザーガイド*の[クライアント側の暗号化を使用したデータの保護](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingClientSideEncryption.html)にて説明されているステップに従います。使用する追加の要件はこちらです:
+ **対称暗号化** – AWS SDK for Java `AmazonS3EncryptionClient` クラスは、前述の、対称キー暗号化に基づくエンベロープ暗号化を使用します。このクラスを使用して、Amazon S3 クライアントを作成し、クライアント側暗号化データをアップロードします。
+ **256 ビット AES ルート対称キー** – ルートキーはエンベロープキーを暗号化します。ルートキーは、`AmazonS3EncryptionClient` クラスのインスタンスに渡す必要があります。このキーは、Amazon Redshift にデータをコピーするときに必要になるので、キーを保存する必要があります。
+ **暗号化されたエンベロープキーを保存するオブジェクトメタデータ** — Amazon S3 のデフォルトでは、エンベロープキーは `AmazonS3EncryptionClient` クラスのオブジェクトメタデータとして保存されます。オブジェクトメタデータとして保存された暗号化されたエンベロープキーは、復号プロセスで使用されます。

**注記**  
初めて暗号化 API を使用するときに暗号の暗号化エラーメッセージが表示される場合、使用する JDK のバージョンに、暗号化/復号変換に使用する最大キー長を 128 ビットに制限する Java Cryptography Extension (JCE) 管轄ポリシーファイルが含まれている可能性があります。この問題に対処する方法については、*Amazon Simple Storage Service ユーザーガイド*の「[AWS SDK for Java を使用したクライアント側の暗号化の指定](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingClientSideEncryptionUpload.html)」を参照してください。

クライアント側で暗号化したファイルを COPY コマンドを使用して Amazon Redshift テーブルにロードする方法については、[暗号化されたデータファイルを Amazon S3 からロードする](c_loading-encrypted-files.md) を参照してください。

## 例: クライアント側暗号化データのアップロード
<a name="client-side-encryption-example"></a>

AWS SDK for Java を使用してクライアント側の暗号化データをアップロードする例については、*Amazon Simple Storage Service ユーザーガイド*の「[クライアント側の暗号化を使用したデータの保護](https://docs.aws.amazon.com/AmazonS3/latest/userguide/encrypt-client-side-symmetric-master-key.html)」を参照してください。

2 つ目のオプションで、データを Amazon Redshift にロードできるように、クライアント側で暗号化を行う際に選択すべき点を示しています。具体的には、オブジェクトメタデータを使用して暗号化されたエンベロープキーを保存する方法と、256 ビット AES マスター対称キーを使用する方法についてです。

ここでは、AWS SDK for Java を使用して 256 ビットの AES 対称ルートキーを作成し、それをファイルに保存するためのコード例を示します。次に、この例ではサンプルデータを S3 暗号化クライアントを使用してクライアント側で最初に暗号化し、オブジェクトを Amazon S3 にアップロードします。この例ではオブジェクトもダウンロードして、データが同じであることを確認します。

# 必要なファイルがバケットにあることを確認する
<a name="verifying-that-correct-files-are-present"></a>

Amazon S3 バケットにファイルをアップロードした後に、バケットの内容を一覧表示し、必要なすべてのファイルが揃っており、不必要なファイルがないことを確認します。例えば、バケット `amzn-s3-demo-bucket` に「`venue.txt.back`」という名前のファイルがある場合、そのファイルは、おそらくは意図しなくても、次のコマンドによりロードされます。

```
COPY venue FROM 's3://amzn-s3-demo-bucket/venue' … ;
```

ロードするファイルを厳密に制御したいのであれば、マニフェストファイルを使用し、データファイルをリストに明示的に指定します。マニフェストファイルの使用に関する詳細は、COPY コマンドの [copy_from_s3_manifest_file](copy-parameters-data-source-s3.md#copy-manifest-file) オプションと COPY 例の [マニフェストを使用し、データファイルを指定する](r_COPY_command_examples.md#copy-command-examples-manifest) を参照してください。

バケット内容のリスト化に関する詳細については、*Amazon S3 デベロッパーガイド*の「[オブジェクトキーのリスト](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ListingKeysUsingAPIs.html)」を参照してください。

# COPY コマンドを使用し、Amazon S3 からロードする
<a name="t_loading-tables-from-s3"></a>

[COPY](r_COPY.md) コマンドを使い、Amazon S3 のデータファイルからテーブルを並列でロードします。Amazon S3 オブジェクトプレフィックスまたはマニフェストファイルを利用し、ロードするファイルを指定できます。

プレフィックスを使ってロードするファイルを指定するための構文は次のようになります。

```
COPY <table_name> FROM 's3://<bucket_name>/<object_prefix>'
authorization;
```

 マニフェストファイルは、ロードするデータファイルのリストを指定する JSON 形式のファイルです。マニフェストファイルを使ってロードするファイルを指定するための構文は次のようになります。

```
COPY <table_name> FROM 's3://<bucket_name>/<manifest_file>'
authorization
MANIFEST;
```

ロードするテーブルはデータベースに存在している必要があります。テーブルの作成に関する詳細は、SQL リファレンスの「[CREATE TABLE](r_CREATE_TABLE_NEW.md)」を参照してください。

許可の値により、Amazon Redshift が Amazon S3 オブジェクトにアクセスするために必要な AWS の許可が提供されます。**必要なアクセス権限については、「[COPY、UNLOAD、CREATE LIBRARY のための IAM のアクセス許可](copy-usage_notes-access-permissions.md#copy-usage_notes-iam-permissions)」を参照してください。推奨の認証方法は、IAM\$1ROLE パラメータを指定して、必要なアクセス権限がある IAM ロールの Amazon リソースネーム (ARN) を提供することです。詳細については、「[ロールベースアクセスコントロール](copy-usage_notes-access-permissions.md#copy-usage_notes-access-role-based)」を参照してください。

IAM\$1ROLE パラメータを使用して認証するには、次の構文で示すように、*<aws-account-id>* および *<role-name>* を置き換えます。

```
IAM_ROLE 'arn:aws:iam::<aws-account-id>:role/<role-name>'
```

次の例で、IAM ロールを使用した認証を示します。

```
COPY customer 
FROM 's3://amzn-s3-demo-bucket/mydata' 
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

他の認証オプションの詳細については、「[認可パラメータ](copy-parameters-authorization.md)」を参照してください。

テーブルを実際にロードせずにデータを検証する場合、[COPY](r_COPY.md) コマンドに NOLOAD オプションを指定します。

次の例では、「`venue.txt`」という名前のファイルのパイプ区切りデータの最初の数行を示しています。

```
1|Toyota Park|Bridgeview|IL|0
2|Columbus Crew Stadium|Columbus|OH|0
3|RFK Stadium|Washington|DC|0
```

Amazon S3 にファイルをアップロードする前に、ファイルを複数のファイルに分割します。分割されたファイルは COPY コマンドで並列処理を使ってロードされます。ファイルの数はクラスター内のスライスの数の倍数である必要があります。ロードデータファイルを分割して大体同じサイズにし、圧縮後に 1 MB ～ 1 GB になるようにします。詳細については、「[圧縮および非圧縮のファイルからのデータのロード](t_splitting-data-files.md)」を参照してください。

例えば、`venue.txt` ファイルを次のように 4 つのファイルに分割します。

```
venue.txt.1
venue.txt.2
venue.txt.3
venue.txt.4
```

次の COPY コマンドは Amazon S3 バケット `amzn-s3-demo-bucket` でプレフィックスが「venue」になっているデータファイルのパイプ区切りデータを使って VENUE テーブルをロードします。

**注記**  
次の例の Amazon S3 バケット `amzn-s3-demo-bucket` は存在しません。既存の Amazon S3 バケットの実データを使用した、COPY コマンドのサンプルについては、「[サンプルデータをロードする](https://docs.aws.amazon.com/redshift/latest/gsg/cm-dev-t-load-sample-data.html)」を参照してください。

```
COPY venue FROM 's3://amzn-s3-demo-bucket/venue'
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
DELIMITER '|';
```

「venue」というキープレフィックスのある Amazon S3 オブジェクトが存在しない場合、ロードは失敗します。

**Topics**
+ [マニフェストを使用し、データファイルを指定する](loading-data-files-using-manifest.md)
+ [圧縮されたデータファイルを Amazon S3 からロードする](t_loading-gzip-compressed-data-files-from-S3.md)
+ [Amazon S3 から固定幅データをロードする](t_loading_fixed_width_data.md)
+ [Amazon S3 からマルチバイトのデータをロードする](t_loading_unicode_data.md)
+ [暗号化されたデータファイルを Amazon S3 からロードする](c_loading-encrypted-files.md)

# マニフェストを使用し、データファイルを指定する
<a name="loading-data-files-using-manifest"></a>

COPY コマンドにより必要なすべてのファイルのみがロードされるように、データロードにマニフェストを使用できます。マニフェストを使用し、異なるバケットからファイルをロードしたり、同じプレフィックスを共有しないファイルをロードしたりできます。この場合、COPY コマンドにオブジェクトパスを指定する代わりに、ロードするファイルのリストを JSON 形式のテキストファイルに明示的に指定します。マニフェスト内の URL ではプレフィックスだけでなく、バケットの名前とファイルの完全なオブジェクトパスを指定しておく必要があります。

マニフェストファイルの詳細については、「[マニフェストを使用し、データファイルを指定する](r_COPY_command_examples.md#copy-command-examples-manifest)」を参照してください。

次の例では、バケットが異なり、ファイル名が日付スタンプで始まるファイルをロードする JSON を示しています。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket1/2013-10-04-custdata", "mandatory":true},
    {"url":"s3://amzn-s3-demo-bucket1/2013-10-05-custdata", "mandatory":true},
    {"url":"s3://amzn-s3-demo-bucket2/2013-10-04-custdata", "mandatory":true},
    {"url":"s3://amzn-s3-demo-bucket2/2013-10-05-custdata", "mandatory":true}
  ]
}
```

ファイルが見つからない場合に、オプションの `mandatory` フラグによって COPY コマンドがエラーを返すかどうかを指定します。`mandatory` のデフォルトは `false` です。mandatory 設定と関係なく、どのファイルも見つからない場合、COPY は終了します。

次の例では、前の例にあった「`cust.manifest`」という名前のマニフェストで COPY コマンドを実行しています。

```
COPY customer
FROM 's3://amzn-s3-demo-bucket/cust.manifest' 
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
MANIFEST;
```

## UNLOAD で作成されたマニフェストの使用
<a name="loading-data-files-using-unload-manifest"></a>

MANIFEST パラメータを使用して [UNLOAD](r_UNLOAD.md) オペレーションで作成したマニフェストには、COPY オペレーションに必要ないキーが含まれている場合があります。例えば、次の `UNLOAD` マニフェストには、Amazon Redshift Spectrum の外部テーブルと `ORC` または `Parquet` ファイル形式でデータファイルをロードするのに必要な `meta` キーが含まれています。`meta` キーには、ファイルの実際のサイズの値 (バイト) の `content_length` キーが含まれます。COPY オペレーションに必要なのは `url` キーとオプションの `mandatory` キーのみです。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket/unload/manifest_0000_part_00", "meta": { "content_length": 5956875 }},
    {"url":"s3://amzn-s3-demo-bucket/unload/unload/manifest_0001_part_00", "meta": { "content_length": 5997091 }}
 ]
}
```

マニフェストファイルについて詳しくは、「[マニフェストを使用し、データファイルを指定する](r_COPY_command_examples.md#copy-command-examples-manifest)」を参照してください。

# 圧縮されたデータファイルを Amazon S3 からロードする
<a name="t_loading-gzip-compressed-data-files-from-S3"></a>

gzip、lzop、または bzip2 で圧縮されたデータファイルをロードするには、対応する GZIP、LZOP、または BZIP2 オプションを含めます。

例えば、次のコマンドは lzop で圧縮されたファイルをロードします。

```
COPY customer FROM 's3://amzn-s3-demo-bucket/customer.lzo' 
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
DELIMITER '|' LZOP;
```

**注記**  
データファイルを lzop で圧縮して *--filter* オプションを使用する場合、COPY コマンドはこのオプションをサポートしません。

# Amazon S3 から固定幅データをロードする
<a name="t_loading_fixed_width_data"></a>

固定幅データファイルでは、データの各列の長さが統一されています。固定幅データファイルの各フィールドでは、長さと位置がまったく同じです。固定幅データファイルの文字データ (CHAR と VARCHAR) については、幅を統一するために、プレースホルダーとして先行または後続スペースを含める必要があります。整数については、プレースホルダーとして先行ゼロを含める必要があります。固定幅データファイルには列を分割する区切り文字がありません。

固定幅データファイルを既存のテーブルにロードするには、COPY コマンドで FIXEDWIDTH パラメータを使用します。データを正しくロードするには、テーブル仕様が fixedwidth\$1spec の値に一致する必要があります。

ファイルからテーブルに固定幅データをロードするには、次のコマンドを発行します。

```
COPY table_name FROM 's3://amzn-s3-demo-bucket/prefix' 
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
FIXEDWIDTH 'fixedwidth_spec';
```

*fixedwidth\$1spec* パラメータは、各列の ID と各列の幅がコロンで区切られて指定されている文字列です。**column:width** ペアはカンマで区切られています。ID には数字、文字、またはその 2 つの組み合わせを自由に選択できます。ID とテーブル自体の間には何の関係もありません。そのため、仕様にテーブルと同じ順序で列を含める必要があります。

次の 2 つの例では同じ仕様を示していますが、最初の例では数字の ID を使用し、2 つ目の例では文字列の ID を使用しています。

```
'0:3,1:25,2:12,3:2,4:6'
```

```
'venueid:3,venuename:25,venuecity:12,venuestate:2,venueseats:6'
```

次の例では、前述の仕様を使用して VENUE テーブルにロードするサンプルの固定幅データを示しています。

```
1  Toyota Park               Bridgeview  IL0
2  Columbus Crew Stadium     Columbus    OH0
3  RFK Stadium               Washington  DC0
4  CommunityAmerica Ballpark Kansas City KS0
5  Gillette Stadium          Foxborough  MA68756
```

次の COPY コマンドではこのデータセットが VENUE テーブルにロードされます。

```
COPY venue
FROM 's3://amzn-s3-demo-bucket/data/venue_fw.txt' 
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
FIXEDWIDTH 'venueid:3,venuename:25,venuecity:12,venuestate:2,venueseats:6';
```

# Amazon S3 からマルチバイトのデータをロードする
<a name="t_loading_unicode_data"></a>

データに ASCII 以外のマルチバイト文字 (漢字やキリル文字) が含まれる場合、データを VARCHAR 列にロードする必要があります。VARCHAR データ型は 4 バイトの UTF-8 文字をサポートしますが、CHAR データ型はシングルバイトの ASCII 文字のみを受け取ります。5 バイト以上の文字を Amazon Redshift テーブルにロードすることはできません。CHAR と VARCHAR に関する詳細は、「[データ型](c_Supported_data_types.md)」を参照してください。

入力ファイルで使用されるエンコーディングを確認するには、Linux * `file`* コマンドを使用します: 

```
$ file ordersdata.txt
ordersdata.txt: ASCII English text
$ file uni_ordersdata.dat
uni_ordersdata.dat: UTF-8 Unicode text
```

# 暗号化されたデータファイルを Amazon S3 からロードする
<a name="c_loading-encrypted-files"></a>

COPY コマンドを使い、サーバー側の暗号化、クライアント側の暗号化、またはその両方を使用して Amazon S3 にアップロードされたデータファイルをロードすることができます。

COPY コマンドは、次のタイプの Amazon S3 の暗号化をサポートします。
+ Amazon S3 で管理されたキーを使用したサーバー側の暗号化 (SSE-S3)
+ AWS KMS keys (SSE-KMS) によるサーバー側の暗号化
+ クライアント側対称ルートキーを使用したクライアント側の暗号化

COPY コマンドは、次のタイプの Amazon S3 の暗号化をサポートしません。
+ お客様が用意したキーを使用したサーバー側の暗号化 (SSE-C)
+ AWS KMS key を使用したクライアント側の暗号化
+ お客様が提供する非対称ルートキーを使用したクライアント側の暗号化

Amazon S3 暗号化の詳細については、Amazon Simple Storage Service ユーザーガイドの[サーバー側の暗号化を使用したデータの保護](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html)および[クライアント側の暗号化を使用したデータの保護](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingClientSideEncryption.html)を参照してください。

[UNLOAD](r_UNLOAD.md) コマンドは SSE-S3 を使用して自動的にファイルを暗号化します。また、カスタマー管理型の対象キーによる SSE-KMS またはクライアント側の暗号化を使用してアンロードすることもできます。詳細については、[暗号化されたデータファイルをアンロードする](t_unloading_encrypted_files.md)を参照してください。

COPY コマンドは SSE-S3 と SSE-KMS を使用して暗号化されたファイルを自動的に認識してロードします。ENCRYPTED オプションを使用し、キーの値を指定することで、クライアント側対称ルートキーで暗号化されたファイルをロードできます。詳細については、「[Amazon S3 への暗号化されたデータのアップロード](t_uploading-encrypted-data.md)」を参照してください。

クライアント側で暗号化されたデータファイルをロードするには、MASTER\$1SYMMETRIC\$1KEY パラメータを使用しながらルートキーの値を指定し、そこに ENCRYPTED オプションを含めます。

```
COPY customer FROM 's3://amzn-s3-demo-bucket/encrypted/customer' 
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
MASTER_SYMMETRIC_KEY '<root_key>' 
ENCRYPTED
DELIMITER '|';
```

gzip、lzop、または bzip2 で圧縮された暗号化データファイルをロードするには、ルートキーの値とともに GZIP、LZOP、または BZIP2 オプションを含め、さらに ENCRYPTED オプションを含めます。

```
COPY customer FROM 's3://amzn-s3-demo-bucket/encrypted/customer' 
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
MASTER_SYMMETRIC_KEY '<root_key>'
ENCRYPTED 
DELIMITER '|' 
GZIP;
```

# Amazon EMR からのデータのロード
<a name="loading-data-from-emr"></a>

COPY コマンドを使用することで、クラスターの Hadoop Distributed File System (HDFS) に、固定幅ファイル、文字区切りファイル、CSV ファイル、または JSON 形式ファイルでテキストファイルを書き込むように設定された Amazon EMR クラスターから、データを並列にロードできます。

## Amazon EMR からデータをロードするプロセス
<a name="load-from-emr-process"></a>

このセクションでは、Amazon EMR クラスターからデータをロードする手順について説明します。以下のセクションでは、各ステップで必要な操作の詳細を説明します。
+ **[ステップ 1: IAM のアクセス許可を設定する](#load-from-emr-steps-configure-iam)**

  Amazon EMR クラスターを作成して Amazon Redshift の COPY コマンドを実行するユーザーには、そのための許可が必要です。
+ **[ステップ 2: Amazon EMR クラスターを作成する](#load-from-emr-steps-create-cluster)**

  テキストファイルを Hadoop Distributed File System（HDFS）に出力するようにクラスターの設定を変更します。Amazon EMR クラスター ID およびそのクラスターのメインの公開 DNS (クラスターをホストする Amazon EC2 インスタンスのエンドポイント) が必要になります。
+ **[ステップ 3: Amazon Redshift クラスターの公開キーおよびクラスターノード IP アドレスを取得する](#load-from-emr-steps-retrieve-key-and-ips)**

  公開キーは、Amazon Redshift クラスターノードがホストへの SSH 接続を確立するために使用されます。ホストのセキュリティグループに各クラスターノードの IP アドレスを設定し、その IP アドレスで Amazon Redshift クラスターからアクセスできるようにします。
+ **[ステップ 4: 各 Amazon EC2 ホストの承認されたキーファイルに Amazon Redshift クラスターの公開キーを追加する](#load-from-emr-steps-add-key-to-host)** 

  ホストが Amazon Redshift クラスターを認識し、SSH 接続を許可するように、ホストの認可されたキーファイルに Amazon Redshift クラスターの公開キーを追加します。
+ **[ステップ 5: Amazon Redshift クラスターの IP アドレスすべてを許可するようにホストを設定する](#load-from-emr-steps-configure-security-groups)** 

  Amazon EMR インスタンスのセキュリティグループを変更して、Amazon Redshift の IP アドレスを許可する入力ルールを追加します。
+ **[ステップ 6: COPY コマンドを実行してデータをロードする](#load-from-emr-steps-run-copy)**

  Amazon Redshift データベースから COPY コマンドを実行して、Amazon Redshift テーブルにデータをロードします。

## ステップ 1: IAM のアクセス許可を設定する
<a name="load-from-emr-steps-configure-iam"></a>

Amazon EMR クラスターを作成して Amazon Redshift の COPY コマンドを実行するユーザーには、そのための許可が必要です。

**IAM のアクセス許可を設定するには**

1. Amazon EMR クラスターを作成するユーザーに以下のアクセス許可を追加します。

   ```
   ec2:DescribeSecurityGroups
   ec2:RevokeSecurityGroupIngress
   ec2:AuthorizeSecurityGroupIngress
   redshift:DescribeClusters
   ```

1. COPY コマンドを実行する IAM ロールまたはユーザーに以下のアクセス許可を追加します。

   ```
   elasticmapreduce:ListInstances
   ```

1. Amazon EMR クラスターの IAM ロールに次のアクセス許可を追加します。

   ```
   redshift:DescribeClusters
   ```

## ステップ 2: Amazon EMR クラスターを作成する
<a name="load-from-emr-steps-create-cluster"></a>

COPY コマンドでは、Amazon EMR の Hadoop Distributed File System (HDFS) のファイルからデータをロードします。Amazon EMR クラスターを作成する場合には、クラスターの HDFS にデータファイルを出力するようにクラスターを設定する必要があります。

**Amazon EMR クラスターを作成するには**

1. Amazon Redshift クラスターと同じ AWS リージョンに Amazon EMR クラスターを作成します。

   Amazon Redshift クラスターが VPC にある場合、Amazon EMR クラスターも同じ VPC グループにある必要があります。Amazon Redshift クラスターで EC2-Classic モードを使用する (つまり、そのクラスターが VPC にない) 場合は、Amazon EMR クラスターでも EC2 Classic モードを使用する必要があります。詳細については、「*Amazon Redshift 管理ガイド*」の「[仮想プライベートクラウド (VPC) でクラスターを管理する](https://docs.aws.amazon.com/redshift/latest/mgmt/managing-clusters-vpc.html)」を参照してください。

1. クラスターの HDFS にデータファイルを出力するようにクラスターを設定します。HDFS ファイル名にアスタリスク (\$1) と疑問符 (?) は使用できません。
**重要**  
ファイル名にアスタリスク (\$1) と疑問符 (?) は使用できません。

1. COPY コマンドの実行中もクラスターを継続して使用できるように、Amazon EMR クラスター設定の **[Auto-terminate]** (自動終了) オプションで **[No]** (いいえ) を指定します。
**重要**  
COPY が完了する前にデータ ファイルのいずれかが変更または削除されると、予期しない結果を招いたり、COPY 操作が失敗したりする可能性があります。

1. クラスター ID およびメインの公開 DNS (クラスターをホストする Amazon EC2 インスタンスのエンドポイント) を書き留めておいてください。この情報は、後のステップで使用します。

## ステップ 3: Amazon Redshift クラスターの公開キーおよびクラスターノード IP アドレスを取得する
<a name="load-from-emr-steps-retrieve-key-and-ips"></a>

ホストのセキュリティグループに各クラスターノードの IP アドレスを設定し、その IP アドレスで Amazon Redshift クラスターからアクセスできるようにします。

**コンソールを使用して Amazon Redshift クラスター公開キーとクラスターのクラスターノード IP アドレスを取得する方法は、以下のとおりです。**

1. Amazon Redshift マネジメントコンソールにアクセスします。

1. ナビゲーションペインで **[Clusters]** (クラスター) リンクを選択します。

1. リストからクラスターを選択します。

1. [**SSH 取り込み設定**] グループを探します。

   [**クラスターパブリックキー**] と [**ノード IP アドレス**] の内容を書き留めておきます。この 2 つは、後のステップで使用します。  
![\[クラスターのパブリックキーとノードの IP アドレスを示す SSH 取り込み設定グループのスクリーンショット。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/copy-from-ssh-console-2.png)

   このプライベート IP アドレスは、ステップ 3 で Amazon Redshift からの接続を許可するように Amazon EC2 ホストを設定するために使用します。

Amazon Redshift CLI を使用してクラスター公開キーとクラスターノード の IP アドレスを取得するには、describe-clusters コマンドを実行します。例: 

```
aws redshift describe-clusters --cluster-identifier <cluster-identifier> 
```

応答には、以下のような ClusterPublicKey 値とプライベートおよびパブリック IP アドレスのリストが含まれます。

```
{
    "Clusters": [
        {
            "VpcSecurityGroups": [], 
            "ClusterStatus": "available", 
            "ClusterNodes": [
                {
                    "PrivateIPAddress": "10.nnn.nnn.nnn", 
                    "NodeRole": "LEADER", 
                    "PublicIPAddress": "10.nnn.nnn.nnn"
                }, 
                {
                    "PrivateIPAddress": "10.nnn.nnn.nnn", 
                    "NodeRole": "COMPUTE-0", 
                    "PublicIPAddress": "10.nnn.nnn.nnn"
                }, 
                {
                    "PrivateIPAddress": "10.nnn.nnn.nnn", 
                    "NodeRole": "COMPUTE-1", 
                    "PublicIPAddress": "10.nnn.nnn.nnn"
                }
            ], 
            "AutomatedSnapshotRetentionPeriod": 1, 
            "PreferredMaintenanceWindow": "wed:05:30-wed:06:00", 
            "AvailabilityZone": "us-east-1a", 
            "NodeType": "dc2.large", 
            "ClusterPublicKey": "ssh-rsa AAAABexamplepublickey...Y3TAl Amazon-Redshift", 
             ...
             ...
}
```

Amazon Redshift API を使用してクラスターの公開キーとクラスターノード IP アドレスを取得するには、`DescribeClusters` アクションを使用します。詳細については、*Amazon Redshift CLI ガイド*の [describe-clusters](https://docs.aws.amazon.com/cli/latest/reference/redshift/describe-clusters.html) または Amazon Redshift API ガイドの [DescribeClusters](https://docs.aws.amazon.com/redshift/latest/APIReference/API_DescribeClusters.html) を参照してください。

## ステップ 4: 各 Amazon EC2 ホストの承認されたキーファイルに Amazon Redshift クラスターの公開キーを追加する
<a name="load-from-emr-steps-add-key-to-host"></a>

Amazon EMR クラスターノードすべてについて、各ホストの承認されたキーファイルにクラスターの公開キーを追加し、ホストが Amazon Redshift を認識して SSH 接続を許可できるようにします。

**Amazon Redshift クラスターの公開キーをホストの認可されたキーファイルに追加するには**

1. SSH 接続を使用してホストにアクセスします。

   SSH を使用したインスタンスへの接続については、*Amazon EC2 ユーザーガイド*の [インスタンスへの接続](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-connect-to-instance-linux.html)を参照してください。

1. コンソールまたは CLI 応答のテキストから Amazon Redshift の公開キーをコピーします。

1. パブリックキーの内容をコピーして、ホストの `/home/<ssh_username>/.ssh/authorized_keys` ファイルに貼り付けます。プレフィックス "`ssh-rsa`" やサフィックス "`Amazon-Redshift`" も含めた完全な文字列を入力してください。次に例を示します。

   ```
   ssh-rsa AAAACTP3isxgGzVWoIWpbVvRCOzYdVifMrh… uA70BnMHCaMiRdmvsDOedZDOedZ Amazon-Redshift
   ```

## ステップ 5: Amazon Redshift クラスターの IP アドレスすべてを許可するようにホストを設定する
<a name="load-from-emr-steps-configure-security-groups"></a>

 ホストインスタンスへのインバウンドトラフィックを許可するには、セキュリティグループを編集して、Amazon Redshift クラスターノードごとに 1 つのインバウンドルールを追加します。[**タイプ**] として、ポート 22 での TCP プロトコルを使用した SSH を選択します。**[Source]** (ソース) としては、[ステップ 3: Amazon Redshift クラスターの公開キーおよびクラスターノード IP アドレスを取得する](#load-from-emr-steps-retrieve-key-and-ips) で取得した Amazon Redshift クラスターノードのプライベート IP アドレスを入力します。Amazon EC2 セキュリティグループへのルール追加の詳細については、*Amazon EC2 ユーザーガイド*から[インスタンスのインバウンドトラフィックの認可](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html)を参照してください。

## ステップ 6: COPY コマンドを実行してデータをロードする
<a name="load-from-emr-steps-run-copy"></a>

[COPY](r_COPY.md) コマンドを実行して Amazon EMR クラスターに接続し、Amazon Redshift テーブルにデータをロードします。Amazon EMR クラスターは、COPY コマンドが完了するまで稼動している必要があります。例えば、クラスターに対して自動終了は設定しないようにしてください。

**重要**  
COPY が完了する前にデータ ファイルのいずれかが変更または削除されると、予期しない結果を招いたり、COPY 操作が失敗したりする可能性があります。

COPY コマンドでは、Amazon EMR クラスター ID と、HDFS のファイルパスおよびファイル名を指定します。

```
COPY sales
FROM 'emr://myemrclusterid/myoutput/part*' CREDENTIALS 
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

ファイル名の引数にはワイルドカード文字としてアスタリスク (`*`) および疑問符 (`?`) を使用できます。例えば、`part*` であれば、`part-0000`、`part-0001` などのファイルがロードされます。COPY コマンドでフォルダー名のみを指定した場合には、フォルダー内のすべてのファイルがロードされます。

**重要**  
ワイルドカード文字を使用する場合や、フォルダー名のみを指定する場合には、フォルダーを確認して不要なファイルがロードされることのないようにしてください。不要なファイルがロードされると、COPY コマンドが失敗します。例えば、一部のプロセスでは出力フォルダにログファイルが書き込まれることがあります。

# リモートホストからデータをロードする
<a name="loading-data-from-remote-hosts"></a>

COPY コマンドでは、Amazon EC2 インスタンスもしくは他のコンピュータなど、1 つ以上のリモートホストから並列的にデータをロードすることができます。COPY では SSH を使用してリモートホストに接続し、そのホスト上でコマンドを実行しテキスト出力を生成します。

リモートホストになることができるのは、Amazon EC2 の Linux インスタンスか、SSH 接続を許可するように設定されている Unix コンピュータまたは Linux コンピュータです。このガイドでは、リモートホストが Amazon EC2 インスタンスであることを前提としています。これ以外のコンピュータの場合に手順が異なるときは、その都度説明します。

Amazon Redshift は複数のホストに接続でき、各ホストに対して複数の SSH 接続を開くことができます。Amazon Redshift は、各接続を介して一意のコマンドを送信し、ホストの標準出力にテキスト出力を生成します。その後、Amazon Redshift はテキストファイルと同じように読み込みます。

## 開始する前に
<a name="load-from-host-before-you-begin"></a>

開始する前に、以下があることを確認してください。
+ 1 台以上のホストマシン (SSH を使用して接続できる Amazon EC2 インスタンスなど)。
+ ホストのデータソース。

  テキスト出力を生成するために Amazon Redshift クラスターがホストで実行するコマンドを指定します。COPY コマンドは、クラスターがホストに接続するとコマンドを実行し、ホストの標準的な出力先からテキストを読み込み、Amazon Redshift テーブルにデータを並列的にロードします。テキストの出力は、COPY コマンドが取り込むことができる形式であることが必要です。詳細については、「[入力データを準備する](t_preparing-input-data.md)」を参照してください。
+ コンピュータからホストへのアクセス権。

  Amazon EC2 インスタンスでは、ホストにアクセスする際に SSH 接続を使用します。このため、ホストにアクセスし、ホストの承認されたキーファイルに Amazon Redshift クラスターの公開キーを追加する必要があります。
+ 実行中の Amazon Redshift クラスター。

  クラスターを起動する方法については、[Amazon Redshift 入門ガイド](https://docs.aws.amazon.com/redshift/latest/gsg/)を参照してください。

## データをロードする手順
<a name="load-from-host-process"></a>

このセクションでは、リモートホストからデータをロードする手順を説明します。以下のセクションでは、各ステップで必要な操作の詳細を説明します。
+ **[ステップ 1: クラスターパブリックキーおよびクラスターノード IP アドレスを取得する](#load-from-host-steps-retrieve-key-and-ips)**

  公開キーは、Amazon Redshift クラスターノードがリモートホストへの SSH 接続を確立するために使用されます。各クラスターノードの IP アドレスを使用して、その IP アドレスによる Amazon Redshift クラスターからのアクセスを許可するように、ホストのセキュリティグループまたはファイアウォールを設定します。
+ **[ステップ 2: ホストの承認されたキーファイルに Amazon Redshift クラスターの公開キーを追加する](#load-from-host-steps-add-key-to-host)**

  ホストが Amazon Redshift クラスターを認識し、SSH 接続を許可するように、ホストの認可されたキーファイルに Amazon Redshift クラスターの公開キーを追加します。
+ **[ステップ 3: Amazon Redshift クラスターの IP アドレスすべてを許可するようにホストを設定する](#load-from-host-steps-configure-security-groups)** 

  Amazon EC2 の場合、インスタンスのセキュリティグループを変更して、Amazon Redshift の IP アドレスを許可する入力ルールを追加します。他のホストの場合には、Amazon Redshift ノードがリモートホストに対して SSH 接続を確立できるようにファイアウォールを設定します。
+ **[ステップ 4: ホストのパブリックキーを取得する](#load-from-host-steps-get-the-host-key)**

  Amazon Redshift がホストの識別に公開キーを使用するように指定することもできます。この場合、パブリックキーを探してマニフェストファイルにテキストをコピーする必要があります。
+ **[ステップ 5: マニフェストファイルを作成する](#load-from-host-steps-create-manifest)** 

  マニフェストは、Amazon Redshift がホストに接続し、データを取得する際に必要になる詳細情報が記載された JSON 形式のテキストファイルです。
+ **[ステップ 6: Amazon S3 バケットにマニフェストファイルをアップロードする](#load-from-host-steps-upload-manifest)** 

  Amazon Redshift はマニフェストを読み込み、その情報を使ってリモートホストに接続します。Amazon S3 バケットが Amazon Redshift クラスターと同じリージョンに存在しない場合は、[REGION](copy-parameters-data-source-s3.md#copy-region) オプションを使用して、データがあるリージョンを指定する必要があります。
+ **[ステップ 7: COPY コマンドを実行してデータをロードする](#load-from-host-steps-run-copy)**

  Amazon Redshift データベースから COPY コマンドを実行して、Amazon Redshift テーブルにデータをロードします。

## ステップ 1: クラスターパブリックキーおよびクラスターノード IP アドレスを取得する
<a name="load-from-host-steps-retrieve-key-and-ips"></a>

ホストのセキュリティグループに各クラスターノードの IP アドレスを設定し、その IP アドレスで Amazon Redshift クラスターからアクセスできるようにします。

**コンソールを使用してクラスターパブリックキーとクラスターのクラスターノード IP アドレスを取得する方法は、以下のとおりです。**

1. Amazon Redshift マネジメントコンソールにアクセスします。

1. ナビゲーションペインで **[Clusters]** (クラスター) リンクを選択します。

1. リストからクラスターを選択します。

1. [**SSH 取り込み設定**] グループを探します。

   [**クラスターパブリックキー**] と [**ノード IP アドレス**] の内容を書き留めておきます。この 2 つは、後のステップで使用します。  
![\[クラスターのパブリックキーとノードの IP アドレスを示す SSH 取り込み設定グループのスクリーンショット。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/copy-from-ssh-console-2.png)

   この IP アドレスは、ステップ 3 で Amazon Redshift からの接続を許可するようにホストを設定するために使用します。接続するホストの種類や、ホストが VPC であるかに応じて、パブリック IP アドレスとプライベート IP アドレスのどちらかを使用します。

Amazon Redshift CLI を使用してクラスター公開キーとクラスターノード の IP アドレスを取得するには、describe-clusters コマンドを実行します。

例: 

```
aws redshift describe-clusters --cluster-identifier <cluster-identifier> 
```

 応答には、以下のような ClusterPublicKey 値とプライベートおよびパブリック IP アドレスのリストが含まれます。

```
{
    "Clusters": [
        {
            "VpcSecurityGroups": [], 
            "ClusterStatus": "available", 
            "ClusterNodes": [
                {
                    "PrivateIPAddress": "10.nnn.nnn.nnn", 
                    "NodeRole": "LEADER", 
                    "PublicIPAddress": "10.nnn.nnn.nnn"
                }, 
                {
                    "PrivateIPAddress": "10.nnn.nnn.nnn", 
                    "NodeRole": "COMPUTE-0", 
                    "PublicIPAddress": "10.nnn.nnn.nnn"
                }, 
                {
                    "PrivateIPAddress": "10.nnn.nnn.nnn", 
                    "NodeRole": "COMPUTE-1", 
                    "PublicIPAddress": "10.nnn.nnn.nnn"
                }
            ], 
            "AutomatedSnapshotRetentionPeriod": 1, 
            "PreferredMaintenanceWindow": "wed:05:30-wed:06:00", 
            "AvailabilityZone": "us-east-1a", 
            "NodeType": "dc2.large", 
            "ClusterPublicKey": "ssh-rsa AAAABexamplepublickey...Y3TAl Amazon-Redshift", 
             ...
             ...
}
```

Amazon Redshift API を使用してクラスターの公開キーとクラスターノード IP アドレスを取得するには、DescribeClusters アクションを使用します。詳細については、*Amazon Redshift CLI ガイド*の [describe-clusters](https://docs.aws.amazon.com/cli/latest/reference/redshift/describe-clusters.html) または Amazon Redshift API ガイドの [DescribeClusters](https://docs.aws.amazon.com/redshift/latest/APIReference/API_DescribeClusters.html) を参照してください。

## ステップ 2: ホストの承認されたキーファイルに Amazon Redshift クラスターの公開キーを追加する
<a name="load-from-host-steps-add-key-to-host"></a>

ホストが Amazon Redshift を認識して SSH 接続を許可するように、各ホストの承認されたキーファイルにクラスターの公開キーを追加します。

**Amazon Redshift クラスターの公開キーをホストの認可されたキーファイルに追加するには**

1. SSH 接続を使用してホストにアクセスします。

   SSH を使用したインスタンスへの接続については、*Amazon EC2 ユーザーガイド*の [インスタンスへの接続](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-connect-to-instance-linux.html)を参照してください。

1. コンソールまたは CLI 応答のテキストから Amazon Redshift の公開キーをコピーします。

1. パブリックキーの内容をコピーして、リモートホストの `/home/<ssh_username>/.ssh/authorized_keys` ファイルに貼り付けます。`<ssh_username>` は、マニフェストファイルの [username] フィールドの値と一致している必要があります。プレフィックス "`ssh-rsa`" やサフィックス "`Amazon-Redshift`" も含めた完全な文字列を入力してください。次に例を示します。

   ```
   ssh-rsa AAAACTP3isxgGzVWoIWpbVvRCOzYdVifMrh… uA70BnMHCaMiRdmvsDOedZDOedZ Amazon-Redshift
   ```

## ステップ 3: Amazon Redshift クラスターの IP アドレスすべてを許可するようにホストを設定する
<a name="load-from-host-steps-configure-security-groups"></a>

 Amazon EC2 インスタンスまたは Amazon EMR クラスターを使用する場合は、ホストのセキュリティグループにインバウンドルールを追加して、各 Amazon Redshift クラスターノードからのトラフィックを許可します。[**タイプ**] として、ポート 22 での TCP プロトコルを使用した SSH を選択します。[**Source (ソース)**] には、[ステップ 1: クラスターパブリックキーおよびクラスターノード IP アドレスを取得する](#load-from-host-steps-retrieve-key-and-ips) で取得した Amazon Redshift クラスターノード IP アドレスを入力します。Amazon EC2 セキュリティグループへのルール追加の詳細については、*Amazon EC2 ユーザーガイド*から[インスタンスのインバウンドトラフィックの認可](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html)を参照してください。

プライベート IP アドレスを使用する局面は、以下のとおりです。
+ Virtual Private Cloud (VPC) に存在しない Amazon Redshift クラスターと Amazon EC2 - Classic インスタンスがいずれも同じ AWS リージョンにある場合。
+  VPC に存在する Amazon Redshift クラスターと Amazon EC2 - VPC インスタンスがいずれも同じ AWS リージョンにあり、かつ同じ VPC に存在する場合。

 これ以外の場合には、パブリック IP アドレスを使用します。

VPC での Amazon Redshift の使用についての詳細は、「*Amazon Redshift 管理ガイド*」の「[仮想プライベートクラウド (VPC) でクラスターを管理する](https://docs.aws.amazon.com/redshift/latest/mgmt/managing-clusters-vpc.html)」を参照してください。

## ステップ 4: ホストのパブリックキーを取得する
<a name="load-from-host-steps-get-the-host-key"></a>

Amazon Redshift がホストを識別できるように、マニフェストファイルでホストの公開キーを指定することもできます。COPY コマンドではホストのパブリックキーは必須でないものの、セキュリティの観点から「中間者 (MITM) 」攻撃の予防のため、パブリックキーを使用することを強くお勧めしています。

ホストのパブリックキーは、以下の場所にあります。ここで `<ssh_host_rsa_key_name>` は、ホストのパブリックキーのユニーク名です。

```
:  /etc/ssh/<ssh_host_rsa_key_name>.pub
```

**注記**  
Amazon Redshift は RSA キーのみをサポートしています。DSA キーはサポートしていません。

パブリックキーのテキストは、ステップ 5 でマニフェストファイルを作成するときにマニフェストファイルのエントリにある [Public Key] フィールドに貼り付けることになります。

## ステップ 5: マニフェストファイルを作成する
<a name="load-from-host-steps-create-manifest"></a>

COPY コマンドは、SSH を使用して複数のホストに接続できるだけでなく、各ホストに対して複数の SSH 接続を作成できます。COPY はそれぞれのホスト接続を介してコマンドを実行し、コマンドからの出力を並列的にテーブルにロードします。マニフェストファイルは、Amazon Redshift がホストに接続する際に使用する JSON 形式のテキストファイルです。マニフェストファイルにより、SSH ホストのエンドポイントと、Amazon Redshift にデータを返すためにそのホストで実行されるコマンドを指定します。このほか、ホストのパブリックキー、ログインユーザー名、および各エントリの必須フラグを記載することもできます。

マニフェストファイルをローカルコンピュータで作成します。後の手順で、Amazon S3 にファイルをアップロードします。

マニフェスト ファイルの形式は以下のとおりです。

```
{ 
   "entries": [ 
     {"endpoint":"<ssh_endpoint_or_IP>", 
       "command": "<remote_command>",
       "mandatory":true, 
       "publickey": "<public_key>", 
       "username": "<host_user_name>"}, 
     {"endpoint":"<ssh_endpoint_or_IP>", 
       "command": "<remote_command>",
       "mandatory":true, 
       "publickey": "<public_key>", 
       "username": "host_user_name"} 
    ] 
}
```

マニフェストファイルには、SSH 接続ごとに 1 つずつ "entries" 構造が含まれます。各エントリは、1 つの SSH 接続を表します。単一のホストに対して接続を複数作成することも、複数のホストに対して複数の接続を作成することもできます。二重引用符は、フィールド名と値のどちらにも必要です。必須フィールドのなかで二重引用符を必要としない値は、**true** または **false** のブール値のみです。

以下に、マニフェストファイルのフィールドについて説明します。

endpoint  
ホストの URL アドレスまたは IP アドレス。例えば、"`ec2-111-222-333.compute-1.amazonaws.com`"、"`22.33.44.56`" などです。

コマンド   
テキストまたはバイナリ (gzip、lzop、または bzip2) の出力を生成する際にホストが実行するコマンド。コマンドは、ユーザー *"host\$1user\$1name"* が実行権限を持つコマンドであれば、どれでも指定できます。ファイルを印刷するなどのシンプルなコマンドでも、データベースにクエリを実行したり、スクリプトを実行したりするコマンドでもかまいません。出力 (テキストファイル、gzip バイナリファイル、lzop バイナリファイル、または bzip2 バイナリファイル) は、Amazon Redshift の COPY コマンドが取り込める形式にする必要があります。詳細については、「[入力データを準備する](t_preparing-input-data.md)」を参照してください。

publickey  
(オプション) ホストのパブリックキー。公開キーが指定されている場合、Amazon Redshift は公開キーを使用してホストを特定します。公開キーが指定されていなければ、Amazon Redshift がホストの特定を試みることはありません。例えば、リモートホストのパブリックキーが `ssh-rsa AbcCbaxxx…xxxDHKJ root@amazon.com` であれば、publickey フィールドには `AbcCbaxxx…xxxDHKJ` と入力してください。

必須  
(オプション) 接続ができなかった場合に COPY コマンドを失敗とするかどうかを示すものです。デフォルトは `false` です。Amazon Redshift が接続を 1 つも正常に確立できなかった場合に、COPY コマンドが失敗になります。

username  
(オプション) ホストシステムにログオンし、リモートコマンドを実行する際に使用するユーザーネーム。ユーザーログイン名は、ステップ 2 でホストの認可されたキーファイルにパブリックキーを追加するときに使用したログイン名と同じものにする必要があります。デフォルトのユーザー名は「redshift」です。

以下の例に、同じホストに対して 4 つの接続を確立し、接続ごとに異なるコマンドを実行するマニフェストの全容を示します。

```
{ 
  "entries": [ 
       {"endpoint":"ec2-184-72-204-112.compute-1.amazonaws.com", 
          "command": "cat loaddata1.txt", 
          "mandatory":true, 
          "publickey": "ec2publickeyportionoftheec2keypair", 
          "username": "ec2-user"}, 
       {"endpoint":"ec2-184-72-204-112.compute-1.amazonaws.com", 
          "command": "cat loaddata2.txt", 
          "mandatory":true, 
          "publickey": "ec2publickeyportionoftheec2keypair", 
          "username": "ec2-user"},
       {"endpoint":"ec2-184-72-204-112.compute-1.amazonaws.com", 
          "command": "cat loaddata3.txt", 
          "mandatory":true, 
          "publickey": "ec2publickeyportionoftheec2keypair", 
          "username": "ec2-user"},
       {"endpoint":"ec2-184-72-204-112.compute-1.amazonaws.com", 
          "command": "cat loaddata4.txt", 
          "mandatory":true, 
          "publickey": "ec2publickeyportionoftheec2keypair", 
          "username": "ec2-user"}
     ] 
}
```

## ステップ 6: Amazon S3 バケットにマニフェストファイルをアップロードする
<a name="load-from-host-steps-upload-manifest"></a>

Amazon S3 バケットにマニフェストファイルをアップロードします。Amazon S3 バケットが Amazon Redshift クラスターと同じ AWS リージョンに存在しない場合は、[REGION](copy-parameters-data-source-s3.md#copy-region) オプションを使用して、マニフェストがある AWS リージョンを指定する必要があります。Amazon S3 バケットの作成およびファイルのアップロードの詳細については、[Amazon Simple Storage Service のユーザーガイド](https://docs.aws.amazon.com/AmazonS3/latest/userguide/)を参照してください。

## ステップ 7: COPY コマンドを実行してデータをロードする
<a name="load-from-host-steps-run-copy"></a>

[COPY](r_COPY.md) コマンドを実行してホストに接続し、Amazon Redshift テーブルにデータをロードします。COPY コマンドでは、マニフェストファイルに Amazon S3 オブジェクトのパスを明示するとともに、SSH オプションを使用します。例: 

```
COPY sales
FROM 's3://amzn-s3-demo-bucket/ssh_manifest'  
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
DELIMITER '|'
SSH;
```

**注記**  
自動圧縮を使用する場合には、COPY コマンドでデータの読み取りが 2 回実行されます。つまりリモートコマンドが 2 回実行されることになります。初回の読み取りは圧縮の分析用サンプルを提供するためのものであり、実際にデータがロードされるのは 2 回目の読み取りです。リモートコマンドを 2 回実行することによる影響が問題になるようであれば、自動圧縮は無効にする必要があります。自動圧縮を無効にするには、COMPUPDATE オプションを OFF に設定して COPY コマンドを実行します。詳細については、「[自動圧縮ありでテーブルをロードする](c_Loading_tables_auto_compress.md)」を参照してください。

# Amazon DynamoDB テーブルからのデータのロード
<a name="t_Loading-data-from-dynamodb"></a>

COPY コマンドで、1 つの Amazon DynamoDB テーブルのデータを使用してテーブルをロードすることができます。

**重要**  
[REGION](copy-parameters-data-source-s3.md#copy-region) オプションを使用して Amazon DynamoDB テーブルがある AWS リージョンを指定しない限り、データを提供する Amazon DynamoDB テーブルは、クラスターと同じ AWS リージョンに作成される必要があります。

COPY コマンドは Amazon Redshift の超並列処理 (MPP) アーキテクチャを使用して、Amazon DynamoDB テーブルからデータを並列でロードします。Amazon Redshift テーブルに分散方式を設定すれば、並列処理を最大限に活用できます。詳細については、「[クエリ最適化のためのデータのディストリビューション](t_Distributing_data.md)」を参照してください。

**重要**  
COPY コマンドで Amazon DynamoDB テーブルからデータを読み込むとき、結果として起こるデータ転送はそのテーブルにプロビジョンドスループットの一部になります。

プロビジョニングされた読み込みスループットの過度の消費を避けるために、本稼働環境にある Amazon DynamoDB テーブルからはデータをロードしないことをお勧めします。本稼働テーブルからデータをロードする場合、プロビジョニングされ、使用されていないスループットの平均パーセントよりかなり低く READRATIO オプションを設定することをお勧めします。READRATIO を低く設定すると、スロットルの問題が最小限に抑えられます。Amazon DynamoDB テーブルにプロビジョンドスループット全体を使用するには、READRATIO を 100 に設定します。

COPY コマンドは以下のルールを使用し、DynamoDB テーブルから取得された項目の属性名と既存の Amazon Redshift テーブルの列名を照合します。
+ Amazon Redshift テーブルの列と Amazon DynamoDB 項目の属性が大文字と小文字を区別せずに照合されます。DynamoDB テーブルの項目に、Price と PRICE のように、大文字/小文字だけが異なる複数の属性が含まれる場合、COPY コマンドは失敗します。
+ Amazon Redshift テーブルの属性と一致しない Amazon DynamoDB テーブル列は、[COPY](r_COPY.md) コマンドの EMPTYASNULL オプションで指定された値に基づき、NULL または空としてロードされます。
+ Amazon Redshift テーブルの列に一致しない Amazon DynamoDB 属性は破棄されます。属性は照合の前に読み込まれます。そのため、破棄された属性もそのテーブルにプロビジョニングされたスループットの一部を消費します。
+ データ型がスカラー STRING と NUMBER の Amazon DynamoDB 属性のみがサポートされます。Amazon DynamoDB BINARY および SET データ型はサポートされません。COPY コマンドがサポートされないデータ型を持つ属性をロードしようとすると失敗します。属性が Amazon Redshift テーブル列に一致しない場合、COPY はロードを試行せず、エラーを発行しません。

COPY コマンドは次の構文を使用し、Amazon DynamoDB テーブルからデータをロードします。

```
COPY <redshift_tablename> FROM 'dynamodb://<dynamodb_table_name>'
authorization
readratio '<integer>';
```

**authorization の値は、Amazon DynamoDB テーブルにアクセスするために必要な AWS の認証情報です。これらの認証情報がユーザーと対応する場合、このユーザーは、ロードする Amazon DynamoDB テーブルに SCAN と DESCRIBE を実行するアクセス許可が必要です。

**authorization の値は、クラスターが Amazon DynamoDB テーブルにアクセスする際に必要な AWS 認証を提供します。許可には、ロードする Amazon DynamoDB テーブルに対する SCAN および DESCRIBE が含まれている必要があります。必要なアクセス権限の詳細については、「[COPY、UNLOAD、CREATE LIBRARY のための IAM のアクセス許可](copy-usage_notes-access-permissions.md#copy-usage_notes-iam-permissions)」を参照してください。推奨の認証方法は、IAM\$1ROLE パラメータを指定して、必要なアクセス権限がある IAM ロールの Amazon リソースネーム (ARN) を提供することです。詳細については、「[ロールベースアクセスコントロール](copy-usage_notes-access-permissions.md#copy-usage_notes-access-role-based)」を参照してください。

IAM\$1ROLE パラメータを使用して認証するには、次の構文で示すように、*<aws-account-id>* および *<role-name>* を置き換えます。

```
IAM_ROLE 'arn:aws:iam::<aws-account-id>:role/<role-name>'
```

次の例で、IAM ロールを使用した認証を示します。

```
COPY favoritemovies 
FROM 'dynamodb://ProductCatalog'
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

他の認証オプションの詳細については、「[認可パラメータ](copy-parameters-authorization.md)」を参照してください。

テーブルを実際にロードせずにデータを検証する場合、[COPY](r_COPY.md) コマンドに NOLOAD オプションを指定します。

次の例では、「my-favorite-movies-table」という名前の DynamoDB テーブルから FAVORITEMOVIES テーブルにデータをロードします。読み取りアクティビティでは、プロビジョニングされたスループットの最大 50% が消費されます。

```
COPY favoritemovies FROM 'dynamodb://my-favorite-movies-table' 
IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
READRATIO 50;
```

スループットを最大化するために、COPY コマンドはクラスターのコンピューティングノード全体で並列で Amazon DynamoDB テーブルからデータをロードします。

## 自動圧縮のあるプロビジョニングされたスループット
<a name="t_Loading-data-from-dynamodb-provisioned-throughput-with-automatic-compression"></a>

デフォルトでは、圧縮エンコーディングなしで空のターゲットテーブルを指定したとき、COPY コマンドは自動圧縮を適用します。自動圧縮分析は、最初に Amazon DynamoDB テーブルから大量の行をサンプリングします。サンプルサイズは、COMPROWS パラメータの値に基づきます。デフォルトはスライスごとに 100,000 行です。

サンプリングの後、サンプル行は破棄され、テーブル全体がロードされます。結果として、多くの行が 2 回読み取られます。自動圧縮の仕組みについては、「[自動圧縮ありでテーブルをロードする](c_Loading_tables_auto_compress.md)」を参照してください。

**重要**  
COPY コマンドで Amazon DynamoDB テーブルからサンプリングで使われる行を含むデータを読み込むと、結果として起こるデータ転送はそのテーブルにプロビジョンドスループットの一部になります。

## Amazon DynamoDB からのマルチバイトデータのロード
<a name="t_Loading-data-from-dynamodb-loading-multibyte-data-from-amazon-dynamodb"></a>

データに ASCII 以外のマルチバイト文字 (漢字やキリル文字) が含まれる場合、データを VARCHAR 列にロードする必要があります。VARCHAR データ型は 4 バイトの UTF-8 文字をサポートしますが、CHAR データ型はシングルバイトの ASCII 文字のみを受け取ります。5 バイト以上の文字を Amazon Redshift テーブルにロードすることはできません。CHAR と VARCHAR に関する詳細は、「[データ型](c_Supported_data_types.md)」を参照してください。

# データが正しくロードされたことを確認する
<a name="verifying-that-data-loaded-correctly"></a>

ロード操作が完了したら、[STL\$1LOAD\$1COMMITS](r_STL_LOAD_COMMITS.md) システムテーブルにクエリし、ファイルが予定どおりロードされたことを確認します。ロードに問題が発生した場合にトランザクション全体をロールバックできるように、COPY コマンドとロードの検証は同じトランザクションで実行します。

次のクエリでは、TICKIT データベースのテーブルをロードするためのエントリが返されます。

```
SELECT query, trim(filename) AS filename, curtime, status
FROM stl_load_commits
WHERE filename like '%tickit%' order by query;


 query |         filename          |          curtime           | status
-------+---------------------------+----------------------------+--------
 22475 | tickit/allusers_pipe.txt  | 2013-02-08 20:58:23.274186 |      1
 22478 | tickit/venue_pipe.txt     | 2013-02-08 20:58:25.070604 |      1
 22480 | tickit/category_pipe.txt  | 2013-02-08 20:58:27.333472 |      1
 22482 | tickit/date2008_pipe.txt  | 2013-02-08 20:58:28.608305 |      1
 22485 | tickit/allevents_pipe.txt | 2013-02-08 20:58:29.99489  |      1
 22487 | tickit/listings_pipe.txt  | 2013-02-08 20:58:37.632939 |      1
 22489 | tickit/sales_tab.txt      | 2013-02-08 20:58:37.632939 |      1
(6 rows)
```

# 入力データを検証する
<a name="t_Validating_input_files"></a>

実際にデータをロードする前に Amazon S3 入力ファイルまたは Amazon DynamoDB テーブルのデータを検証するには、[COPY](r_COPY.md) コマンドとともに NOLOAD オプションを使用します。データをロードする際に使用するものと同じ COPY コマンドおよびオプションとともに NOLOAD を使用します。NOLOAD はデータベースにロードすることなくすべてのデータの完全性をチェックします。NOLOAD オプションは、データのロードを試行した場合に発生する可能性のあるエラーがあればそれらを表示します。

例えば、入力ファイルに間違った Amazon S3 パスを指定した場合、Amazon Redshift は以下のエラーを表示します。

```
ERROR:  No such file or directory
DETAIL:
-----------------------------------------------
Amazon Redshift error:  The specified key does not exist
code:      2
context:   S3 key being read :
location:  step_scan.cpp:1883
process:   xenmaster [pid=22199]
-----------------------------------------------
```

エラーメッセージをトラブルシューティングする方法については、「[ロードエラー参照](r_Load_Error_Reference.md)」を参照してください。

NOLOAD オプションの使用例については、「[NOLOAD オプションを使用する COPY コマンド](r_COPY_command_examples.md#r_COPY_command_examples-load-noload-option)」を参照してください。

# 自動圧縮ありでテーブルをロードする
<a name="c_Loading_tables_auto_compress"></a>

データの独自の評価に基づいて、テーブルの列に圧縮エンコーディングを手動で適用できます。または、COMPUPDATE を ON に設定して COPY コマンドを使用すると、サンプルデータに基づいて自動的に圧縮を分析および適用できます。

新しいテーブルを作成し、ロードするときに自動圧縮を利用できます。COPY コマンドは、圧縮分析を実行します。また、すでに入力されているテーブルに [ANALYZE COMPRESSION](r_ANALYZE_COMPRESSION.md) コマンドを実行すれば、データをロードしたり、テーブルの圧縮を変更したりすることなく圧縮分析を実行できます。例えば、既存のデータ定義言語 (DDL) ステートメントを保持しながら、将来の使用のためにテーブルの圧縮を分析する場合は、ANALYZE COMPRESSION を実行できます。

自動圧縮では、圧縮エンコードを選択する際に全体的なパフォーマンスの負荷を分散させます。ソートキー列が、同じクエリ内の他の列よりもかなり高度に圧縮される場合、範囲が制限されたスキャンはパフォーマンスが低下する可能性があります。その結果、自動圧縮はソートキー列のデータ分析フェーズをスキップし、ユーザー定義のエンコーディングタイプを保持します。

自動圧縮では、エンコードのタイプを明示的に定義していない場合、RAW エンコードが選択されます。ANALYZE COMPRESSION の動作は同じです。最適なクエリパフォーマンスを得るには、ソートキーに RAW を使用することを検討してください。

## 自動圧縮の仕組み
<a name="c_Loading_tables_auto_compress-how-automatic-compression-works"></a>

COMPUPDATE パラメータが ON になっている場合、COPY コマンドは、空のターゲットテーブルで COPY コマンドを実行し、すべてのテーブル列で RAW エンコーディングかエンコーディングなしが設定されている場合に、自動圧縮を適用します。

現在の圧縮エンコーディングに関係なく、空のテーブルに自動圧縮を適用するには、COMPUPDATE オプションを ON に設定して COPY コマンドを実行します。自動圧縮を無効にするには、COMPUPDATE オプションを OFF に設定して COPY コマンドを実行します。

すでにデータが含まれているテーブルには自動圧縮を適用できません。

**注記**  
自動圧縮分析を実行するには、意味のあるサンプルを生成するために十分な行 (少なくともスライスごとに 100,000 行) がロードデータに含まれている必要があります。

自動圧縮では、ロード処理の一部として次の操作がバックグラウンドで実行されます。

1. 行の初回サンプルが入力ファイルからロードされます。サンプルサイズは COMPROWS パラメータの値に基づきます。デフォルトは 100,000 です。

1. 圧縮オプションは列ごとに選択されます。

1. サンプル行がテーブルから削除されます。

1. テーブルは、選択した圧縮エンコーディングで再作成されます。

1. 入力ファイル全体がロードされ、新しいエンコーディングで圧縮されます。

COPY コマンドを実行すると、テーブルが完全にロードされ、圧縮され、使用する準備ができます。その後、追加でデータをロードする場合、追加された行は既存のエンコーディングに基づいて圧縮されます。

圧縮分析のみを実行する場合、ANALYZE COMPRESSION を実行します。完全な COPY を実行するよりも効率的です。その後、結果を評価し、自動圧縮を使用するのか、またはテーブルを手動で再作成するのかを決定できます。

自動圧縮は COPY コマンドでのみサポートされます。代わりに、テーブルを作成するときに圧縮エンコーディングを手動で適用できます。手動圧縮エンコーディングに関する詳細は、「[保存データのサイズを削減するための列圧縮](t_Compressing_data_on_disk.md)」を参照してください。

## 自動圧縮の例
<a name="r_COPY_COMPRESS_examples"></a>

この例では、TICKIT データベースに「BIGLIST」という名前の LISTING テーブルのコピーが含まれており、約 300 万行をロードするときにこのテーブルに自動圧縮を適用するものと仮定します。

**テーブルをロードし、自動的に圧縮するには、次の操作を実行します。**

1. テーブルが空であることを確認します。空のテーブルにのみ自動圧縮を適用できます:

   ```
   TRUNCATE biglist;
   ```

1. 単一の COPY コマンドでテーブルをロードします。テーブルは空であっても、以前のエンコーディングが指定されている可能性があります。Amazon Redshift が圧縮分析を実行できるようにするために、COMPUPDATE パラメータを ON に設定します。

   ```
   COPY biglist FROM 's3://amzn-s3-demo-bucket/biglist.txt' 
   IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
   DELIMITER '|' COMPUPDATE ON;
   ```

   COMPROWS オプションを指定していないため、デフォルトであり、推奨のサンプルサイズである 100,000 行 (スライスごとに) が使用されます。

1. BIGLIST テーブルの新しいスキーマを見て、自動的に選択されたエンコーディングスキームを確認します。

   ```
   SELECT "column", type, encoding 
   from pg_table_def where tablename = 'biglist';
   
   
        Column     |            Type             | Encoding 
   ----------------+-----------------------------+----------
    listid         | integer                     | az64
    sellerid       | integer                     | az64
    eventid        | integer                     | az64
    dateid         | smallint                    | none
    numtickets     | smallint                    | az64
    priceperticket | numeric(8,2)                | az64
    totalprice     | numeric(8,2)                | az64
    listtime       | timestamp without time zone | az64
   ```

1. 予想どおりの数の行がロードされたことを確認します。

   ```
   select count(*) from biglist;
   
   count
   ---------
   3079952
   (1 row)
   ```

後に COPY または INSERT ステートメントを使用してこのテーブルに行が追加されるとき、同じ圧縮エンコーディングが適用されます。

# 細長いテーブルのストレージの最適化
<a name="c_load_compression_hidden_cols"></a>

列の数が非常に少なく、行の数が非常に多いテーブルがある場合、3 つの非表示メタデータ ID 列 (INSERT\$1XID、DELETE\$1XID、ROW\$1ID) がテーブルのディスク領域を過度に消費します。

 非表示列の圧縮を最適化するには、可能な限り、1 回の COPY 処理でテーブルをロードします。複数の別個の COPY コマンドでテーブルをロードする場合、INSERT\$1XID 列は十分に圧縮されません。複数の COPY コマンドを使用する場合、バキューム操作を実行する必要があります。ただし、INSERT\$1XID の圧縮は改善されません。

# デフォルトの列値をロードする
<a name="c_loading_default_values"></a>

任意で COPY コマンドに列のリストを定義できます。このリストに含まれていないテーブルの列については、COPY を実行すると、CREATE TABLE コマンドで指定された DEFAULT オプションにより提供される値か、DEFAULT オプションが指定されていない場合は NULL がロードされます。

COPY を実行し、NOT NULL として定義されている列に NULL を割り当てようとすると、COPY コマンドは失敗します。DEFAULT オプションの割り当てに関する詳細は、「[CREATE TABLE](r_CREATE_TABLE_NEW.md)」を参照してください。

Amazon S3 のデータファイルからロードするとき、リストの列がデータファイルのフィールドと同じ順序になっている必要があります。リストに指定された列に該当するフィールドがデータファイルにない場合、COPY コマンドは失敗します。

Amazon DynamoDB テーブルからロードする場合、順序は関係ありません。Amazon Redshift テーブルの列に一致しない Amazon DynamoDB 属性のフィールドは破棄されます。

COPY コマンドを使って DEFAULT 値をテーブルにロードするとき、次の制限が適用されます。
+ [IDENTITY](r_CREATE_TABLE_NEW.md#identity-clause) 列がリストに含まれる場合、EXPLICIT\$1IDS オプションも [COPY](r_COPY.md) コマンドに指定する必要があります。指定しない場合、COPY コマンドは失敗します。同様に、IDENTITY 列をリストから除外し、EXPLICIT\$1IDS オプションを指定すると、COPY 操作は失敗します。
+ 指定の列に対して評価される DEFAULT 式はロードされるすべての行で同じであるため、RANDOM() 関数を使用する DEFAULT 式はすべての行に同じ値を割り当てます。
+ CURRENT\$1DATE または SYSDATE を含む DEFAULT 式は現在の処理のタイムスタンプに設定されます。

例えば、「[COPY の例](r_COPY_command_examples.md)」の「デフォルト値を使用してファイルのデータをロードする」を参照してください。

# データロードのトラブルシューティング
<a name="t_Troubleshooting_load_errors"></a>

Amazon Redshift のテーブルにデータをロードすると、Amazon S3 からのエラー、無効な入力データ、COPY コマンドエラーが発生する可能性があります。以下のセクションでは、データロードエラーの特定と解決に関する情報を提供します。

**Topics**
+ [S3 イベント統合と COPY JOB のエラーのトラブルシューティング](s3-integration-troubleshooting.md)
+ [S3ServiceException エラー](s3serviceexception-error.md)
+ [データロードをトラブルシューティングするためのシステムテーブル](system-tables-for-troubleshooting-data-loads.md)
+ [マルチバイト文字のロードエラー](multi-byte-character-load-errors.md)
+ [ロードエラー参照](r_Load_Error_Reference.md)

# S3 イベント統合と COPY JOB のエラーのトラブルシューティング
<a name="s3-integration-troubleshooting"></a>

以下の情報を参考にして、Amazon S3 イベント統合や COPY JOB に関して Amazon Redshift でよく起きる問題をトラブルシューティングしてください。

## S3 イベント統合の作成に失敗する
<a name="s3-integration-troubleshooting-creation"></a>

S3 イベント統合の作成が失敗すると、その統合のステータスは `Inactive` になります。Amazon Redshift データウェアハウスに関して、以下の点が正しいことを確認してください。
+ Amazon Redshift のターゲット名前空間に適した認証済みプリンシパルと統合ソースを追加している。「[S3 イベント統合を作成するための前提条件](loading-data-copy-job.md#loading-data-copy-job-prerequisites)」を参照してください。
+ 正しいリソースベースのポリシーをソースの Amazon S3 バケットに追加している。「[S3 イベント統合を作成するための前提条件](loading-data-copy-job.md#loading-data-copy-job-prerequisites)」を参照してください。

## Amazon S3 のデータがターゲットデータベースに表示されない
<a name="s3-integration-troubleshooting-missing-data"></a>

COPY JOB からのデータが表示されない場合は、以下の点を確認してください。
+ SYS\$1COPY\$1JOB\$1DETAIL をクエリして、Amazon S3 ファイルがロードされているか、取り込みが保留中か、またはエラーが起きているかどうかを確認します。詳細については、「[SYS\$1COPY\$1JOB\$1DETAIL](SYS_COPY_JOB_DETAIL.md)」を参照してください。
+ Amazon S3 ファイルが見つからない場合や、想定外の待ち時間が生じている場合は、STL\$1ERROR または SYS\$1COPY\$1JOB\$1INFO を確認します。認証情報エラーや、統合が無効になっていることを示唆する情報が記録されていないか調べてください。詳細については、「[STL\$1ERROR](r_STL_ERROR.md)」および「[SYS\$1COPY\$1JOB\$1INFO](SYS_COPY_JOB_INFO.md)」を参照してください。

# S3ServiceException エラー
<a name="s3serviceexception-error"></a>

最も一般的な s3ServiceException エラーは、異なる AWS リージョンに存在するクラスターやバケットを指定していたり、不十分な Amazon S3 のアクセス許可が記述されていたりする、形式が不適切か不正確である認証情報文字列により引き起こされます。

このセクションでは、各種エラーのトラブルシューティング情報を提供します。

## 無効な認証情報文字列
<a name="invalid-credentials-string-error"></a>

認証情報文字列が不適切にフォーマットされた場合、次のエラーメッセージを受け取ります。

```
ERROR: Invalid credentials. Must be of the format: credentials 
'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>
[;token=<temporary-session-token>]'
```

認証情報文字列にスペースまたは改行が含まれておらず、一重引用符で囲まれていることを確認してください。

## 無効なアクセスキー ID
<a name="invalid-access-key-id-error"></a>

アクセスキー ID が存在しない場合、次のエラーメッセージが表示されます。

```
[Amazon](500310) Invalid operation: S3ServiceException:The AWS Access Key Id you provided does not exist in our records.
```

多くの場合、これはコピーと貼り付けのエラーです。アクセスキー ID を正しく入力したことを確認してください。また、一時的なセッションキーを使用している場合は、`token` の値が設定されていることを確認します。

## 無効なシークレットアクセスキー
<a name="invalid-secret-access-key-error"></a>

シークレットアクセスキーが正しくない場合、次のようなエラーメッセージを受け取ります。

```
[Amazon](500310) Invalid operation: S3ServiceException:The request signature we calculated does not match the signature you provided. 
Check your key and signing method.,Status 403,Error SignatureDoesNotMatch
```

多くの場合、これはコピーと貼り付けのエラーです。シークレットアクセスキーを正しく入力したこと、およびそれがアクセスキー ID 用の正しいキーであることを確認します。

## バケットが異なるリージョンにある
<a name="bucket-in-different-region"></a>

COPY コマンドに指定された Amazon S3 バケットはクラスターと同じ AWS リージョンに置かれている必要があります。Amazon S3 バケットとクラスターが異なるリージョンにある場合、次のようなエラーを受け取ります。

```
ERROR: S3ServiceException:The bucket you are attempting to access must be addressed using the specified endpoint.
```

Amazon S3 マネジメントコンソールを利用してバケットを作成するときにリージョンを選択するか、Amazon S3 API または CLI を利用してバケットを作成するときにエンドポイントを指定することで、特定のリージョンに Amazon S3 バケットを作成できます。詳細については、「[Amazon S3 にファイルをアップロードして COPY で使用する](t_uploading-data-to-S3.md)」を参照してください。

Amazon S3 リージョンの詳細については、*Amazon Simple Storage Service ユーザーガイド*の[バケットへのアクセス](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html#access-bucket-intro)を参照してください。

代わりに、COPY コマンドで [REGION](copy-parameters-data-source-s3.md#copy-region) オプションを使用してリージョンを指定できます。

## アクセスが拒否される
<a name="s3-access-denied-error"></a>

ユーザーに十分なアクセス許可がない場合、次のエラーメッセージを受け取ります。

```
ERROR: S3ServiceException:Access Denied,Status 403,Error AccessDenied
```

考えられる原因の 1 つは、認証情報によって特定されたユーザーが、Amazon S3 バケットへの LIST および GET アクセス権を持っていないことです。その他の原因については、*Amazon Simple Storage Service ユーザーガイド*の「[Amazon S3 でのアクセス拒否 (403 Forbidden) エラーのトラブルシューティング](https://docs.aws.amazon.com/AmazonS3/latest/userguide/troubleshoot-403-errors.html)」を参照してください。

バケットへのユーザーアクセスの管理については、*Amazon Simple Storage Service ユーザーガイド*の「[Amazon S3 での Identity and Access Management](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html)」を参照してください。

# データロードをトラブルシューティングするためのシステムテーブル
<a name="system-tables-for-troubleshooting-data-loads"></a>

以下の Amazon Redshift システムテーブルは、データのロードに関する問題のトラブルシューティングに役立ちます。
+ 特定のロード中に発生したエラーを見つけるには、[STL\$1LOAD\$1ERRORS](r_STL_LOAD_ERRORS.md) にクエリします。
+ 特定のファイルのロード時間を参照したり、特定のファイルが読み取られたかどうかを確認するには、[STL\$1FILE\$1SCAN](r_STL_FILE_SCAN.md) にクエリします。
+ [STL\$1S3CLIENT\$1ERROR](r_STL_S3CLIENT_ERROR.md) にクエリを実行し、Amazon S3 からのデータ転送時に発生したエラーの詳細を調べます。

**ロードエラーを検出し、診断するには、次の操作を実行します。**

1. ロードエラーに関する詳細を返すビューを作成するか、クエリを定義します。次の例では、STL\$1LOAD\$1ERRORS テーブルが STV\$1TBL\$1PERM テーブルと結合し、テーブル ID と実際のテーブル名が照合されます。

   ```
   create view loadview as
   (select distinct tbl, trim(name) as table_name, query, starttime,
   trim(filename) as input, line_number, colname, err_code,
   trim(err_reason) as reason
   from stl_load_errors sl, stv_tbl_perm sp
   where sl.tbl = sp.id);
   ```

1. COPY コマンドの MAXERRORS オプションを十分な大きさの値に設定し、データに関する役に立つ情報を COPY で返せるようにします。COPY でエラーが発生した場合、エラーメッセージにより STL\$1LOAD\$1ERRORS テーブルで詳細を確認するように指示されます。

1. LOADVIEW ビューにクエリし、エラー詳細を確認します。次に例を示します。

   ```
   select * from loadview where table_name='venue';
   ```

   ```
     tbl   | table_name | query |         starttime          
   --------+------------+-------+----------------------------
    100551 | venue      | 20974 | 2013-01-29 19:05:58.365391 
   
   |     input      | line_number | colname | err_code |       reason
   +----------------+-------------+---------+----------+--------------------
   | venue_pipe.txt |           1 |       0 |     1214 | Delimiter not found
   ```

1. ビューが返す情報に基づいて、入力ファイルまたはロードスクリプトの問題を修正します。注意するべき一般的なロードエラーには次のものがあります。
   + テーブルのデータ型と入力データフィールドの値の不一致。
   + テーブルの列数と入力データのフィールド数の不一致。
   + 引用符が一致しません。Amazon Redshift は、一重引用符と二重引用符の両方をサポートしています。ただし、これらの引用符は適切にバランスを取る必要があります。
   + 正しくない入力ファイルの日付/時刻形式。
   + 入力ファイルの値が範囲外 (数値列に関して)。
   + 列の値の数がその圧縮エンコーディングの制限を超えている。

# マルチバイト文字のロードエラー
<a name="multi-byte-character-load-errors"></a>

CHAR データ型の列はシングルバイト UTF-8 文字のみを最大 127 バイトまで、または 16 進数の 7F まで受け取ります。これは ASCII 文字セットでもあります。VARCHAR 列はマルチバイト UTF-8 文字を最大 4 バイトまで受け取ります。詳細については、「[文字型](r_Character_types.md)」を参照してください。

ロードデータの行に列のデータ型として有効でない文字が含まれる場合、COPY はエラーを返し、STL\$1LOAD\$1ERRORS システムログテーブルの行にエラー番号 1220 がログ記録されます。ERR\$1REASON フィールドには無効な文字のバイトシーケンスが 16 進数で含まれます。

ロードデータの無効な文字を修正する代替策は、ロードプロセス中に有効でない文字を置換することです。有効でない UTF-8 文字を置換するには、COPY コマンドに ACCEPTINVCHARS オプション付けて実行します。ACCEPTINVCHARS オプションが設定されている場合は、指定した文字がコードポイントに置き換わります。ACCEPTINVCHARS オプションが設定されていない場合、Amazon Redshift は有効な UTF-8 として文字を受け入れます。詳細については、「[ACCEPTINVCHARS](copy-parameters-data-conversion.md#acceptinvchars)」を参照してください。

次に、有効な UTF-8 で記述したコードポイントのリストを示します。ACCEPTINVCHARS オプションが設定されていない場合、COPY オペレーションはエラーを返しません。また、ここでのコードポイントは有効でない文字で記述されています。[ACCEPTINVCHARS](copy-parameters-data-conversion.md#acceptinvchars) オプションを使用すると、このコードポイントを指定したい文字に置き換えられます。これらのコードポイントには、`0xFDD0` から `0xFDEF` の範囲および 最大で `0x10FFFF` までの値が含まれ、末尾には `FFFE` または `FFFF` の値が付加されます。
+ `0xFFFE`, `0x1FFFE`, `0x2FFFE`, …, `0xFFFFE`, `0x10FFFE`
+ `0xFFFF`, `0x1FFFF`, `0x2FFFF`, …, `0xFFFFF`, `0x10FFFF`

次の例は、COPY により UTF-8 文字の `e0 a1 c7a4` を CHAR 列にロードしようとして発生する、エラーの理由を示しています。

```
Multibyte character not supported for CHAR 
(Hint: Try using  VARCHAR). Invalid char: e0 a1 c7a4
```

エラーが VARCHAR データ型に関連する場合、エラーの理由にはエラーコードと、有効でない UTF-8 16 進数シーケンスが含まれます。次の例では、COPY で UTF-8 `a4` を VARCHAR フィールドにロードしようとした際に発生する、エラーの理由を示しています。

```
String contains invalid or unsupported UTF-8 codepoints. 
Bad UTF-8 hex sequence: a4 (error 3)
```

次のテーブルには、VARCHAR ロードエラーの説明と回避策提案を記載しています。これらのエラーの 1 つが発生した場合、文字を有効な UTF-8 コードシーケンスで置換するか、文字を削除します。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/multi-byte-character-load-errors.html)

# ロードエラー参照
<a name="r_Load_Error_Reference"></a>

ファイルからデータをロードしている間にエラーが発生した場合、[STL\$1LOAD\$1ERRORS](r_STL_LOAD_ERRORS.md) テーブルにクエリしてエラーを特定し、考えられる説明を確認します。次のテーブルは、データロード中に発生する可能性があるすべてのエラーコードの一覧です。

## ロードエラーコード
<a name="r_Load_Error_Reference-load-error-codes"></a>

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_Load_Error_Reference.html)

# S3 イベント統合を作成して Amazon S3 バケットからファイルを自動的にコピーする
<a name="loading-data-copy-job"></a>

**注記**  
自動コピーのプレビューリリースは終了しました。これに伴い、プレビュークラスターは、プレビュー期間の終了日から 30 日後に自動的に削除されます。その後も継続して自動コピーを使う場合は、既存の自動コピージョブを別の Amazon Redshift クラスターで作成し直すことをお勧めします。プレビュークラスターを最新の Amazon Redshift バージョンにアップグレードすることはできません。

自動コピージョブを使用して、Amazon S3 に保存されているファイルから Amazon Redshift テーブルにデータをロードすることができます。Amazon Redshift は、COPY コマンドで指定したパスに新しい Amazon S3 ファイルが追加されると、これを検出します。これに伴い、外部データインジェストパイプラインを作成しなくても、COPY コマンドが自動的に実行されます。Amazon Redshift は、ロードされたファイルを追跡します。Amazon Redshift は、COPY コマンドごとにまとめてバッチ処理されるファイルの数を決定します。結果の COPY コマンドはシステムビューで表示できます。

自動 COPY JOB を作成するには、まず、S3 イベント統合を作成します。ソースの Amazon S3 バケットに新しいファイルが表示されると、Amazon Redshift が COPY コマンドを使用して、それらのファイルのデータベースへのロードを処理します。

## S3 イベント統合を作成するための前提条件
<a name="loading-data-copy-job-prerequisites"></a>

S3 イベント統合をセットアップするには、次の前提条件が満たされていることを確認してください。
+ Amazon S3 バケットには、Amazon S3 の複数のアクセス許可を付与するバケットポリシーが必要です。例えば、次のサンプルポリシーは、*us-east-1* でホストされているリソースバケット `amzn-s3-demo-bucket` に対するアクセス許可を付与します。Amazon S3 バケットと統合が両方とも同じ AWS リージョンにあります。

------
#### [ JSON ]

****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "Auto-Copy-Policy-01",
              "Effect": "Allow",
              "Principal": {
                  "Service": "redshift.amazonaws.com"
                  },
              "Action": [
                  "s3:GetBucketNotification",
                  "s3:PutBucketNotification",
                  "s3:GetBucketLocation"
              ],
              "Resource": "arn:aws:s3:::amzn-s3-demo-bucket:*",
              "Condition": {
                  "ArnLike": {
                      "aws:SourceArn": "arn:aws:redshift:us-east-1:111122223333:integration:*"
                  },
                  "StringEquals": {
                      "aws:SourceAccount": "111122223333"
                  }
              }
          }
      ]
  }
  ```

------
+ ターゲットとなる Amazon Redshift のプロビジョニング済みクラスターまたは Redshift Serverless の名前空間には、バケットへのアクセス許可が必要です。クラスターまたはサーバーレス名前空間に関連付けられている IAM ロールに、適切なアクセス許可を付与する IAM ポリシーがアタッチされていることを確認してください。このポリシーでは、バケットリソース (`amzn-s3-demo-bucket` など) に対する `s3:GetObject` と、バケットリソースとそのコンテンツ (`amzn-s3-demo-bucket/*` など) に対する `s3:ListBucket` を両方とも許可する必要があります。

------
#### [ JSON ]

****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "AutoCopyReadId",
              "Effect": "Allow",
              "Action": [
                  "s3:GetObject",
                  "s3:ListBucket"
              ],
              "Resource": [
                  "arn:aws:s3:::amzn-s3-demo-bucket",  
                  "arn:aws:s3:::amzn-s3-demo-bucket/*" 
              ]
          }
      ]
  }
  ```

------

  IAM ロールに、そのロールの信頼関係を定義したポリシーを追加します。次の例を参照してください。

------
#### [ JSON ]

****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Effect": "Allow",
              "Principal": {
                  "Service": [
                      "redshift.amazonaws.com"
                  ]
              },
              "Action": "sts:AssumeRole"
          }
      ]
  }
  ```

------

  ターゲットのデータウェアハウスがプロビジョニング済みクラスターの場合は、Amazon Redshift コンソールを使用して、該当するプロビジョニング済みクラスターの詳細画面の **[クラスターのアクセス許可]** タブで、そのクラスターに IAM ロールを関連付けることができます。プロビジョニング済みクラスターにロールを関連付ける方法については、「*Amazon Redshift 管理ガイド*」の「[IAM ロールをクラスターに関連付ける](https://docs.aws.amazon.com/redshift/latest/mgmt/copy-unload-iam-role-associating-with-clusters.html)」を参照してください。

  ターゲットのデータウェアハウスが Redshift Serverless である場合は、Redshift Serverless コンソールを使用して、該当するサーバーレス名前空間の詳細画面の **[セキュリティと暗号化]** タブで、その名前空間に IAM ロールを関連付けることができます。サーバーレス名前空間にロールを関連付ける方法については、「*Amazon Redshift 管理ガイド*」の「[Amazon Redshift Serverless へのアクセス許可の付与](https://docs.aws.amazon.com/redshift/latest/mgmt/serverless-security-other-services.html)」を参照してください。
+ Amazon Redshift データウェアハウスには、Amazon S3 バケットへのアクセスを許可するリソースポリシーも必要です。Amazon Redshift コンソールを使用する場合は、S3 イベント統合の作成時に **[修正する]** オプションを選択して、このポリシーを Amazon Redshift データウェアハウスに追加できます。リソースポリシーを自分で更新するには、[put-resource-policy](https://docs.aws.amazon.com/cli/latest/reference/redshift/put-resource-policy.html) AWS CLI コマンドを使用できます。例えば、Amazon S3 バケットとの S3 イベント統合のため、Amazon Redshift のプロビジョニング済みクラスターにリソースポリシーをアタッチするには、次のような AWS CLI コマンドを実行します。次の例は、ユーザーアカウント *123456789012* に対する、*us-east-1* AWS リージョンのプロビジョニング済みクラスターの名前空間のポリシーを示しています。バケットの名前は *amzn-s3-demo-bucket* です。

  ```
  aws redshift put-resource-policy \
  --policy file://rs-rp.json \
  --resource-arn "arn:aws:redshift: us-east-1:123456789012:namespace/cc4ffe56-ad2c-4fd1-a5a2-f29124a56433"
  ```

  ここでは `rs-rp.json` に以下が含まれます。

------
#### [ JSON ]

****  

  ```
  {
  	"Version":"2012-10-17",		 	 	 
  	"Statement": [
  		{
  			"Effect": "Allow",
  			"Principal": {
  				"Service": "redshift.amazonaws.com"
  			},
  			"Action": "redshift:AuthorizeInboundIntegration",
  			"Resource": "arn:aws:redshift:us-east-1:123456789012:namespace:cc4ffe56-ad2c-4fd1-a5a2-f29124a56433",
  			"Condition": {
  				"StringEquals": {
  					"aws:SourceArn": "arn:aws:s3:::amzn-s3-demo-bucket",
  					"aws:SourceAccount": 111122223333
  				}
  			}
  		},
  		{
  			"Effect": "Allow",
  			"Principal": {
  				"AWS": "arn:aws:iam::111122223333:role/myRedshiftRole"
  			},
  			"Action": "redshift:CreateInboundIntegration",
  			"Resource": "arn:aws:redshift:us-east-1:123456789012:namespace:cc4ffe56-ad2c-4fd1-a5a2-f29124a56433",
  			"Condition": {
  				"StringEquals": {
  					"aws:SourceArn": "arn:aws:s3:::amzn-s3-demo-bucket",
  					"aws:SourceAccount": 111122223333
  				}
  			}
  		}
  	]
  }
  ```

------

  Amazon S3 バケットとの S3 イベント統合のため、Redshift Serverless の名前空間にリソースポリシーをアタッチするには、次のような AWS CLI コマンドを実行します。次の例は、ユーザーアカウント *123456789012* に対する、*us-east-1* AWS リージョンのサーバーレス名前空間のポリシーを示しています。バケットの名前は *amzn-s3-demo-bucket* です。

  ```
  aws redshift put-resource-policy \
  --policy file://rs-rp.json \
  --resource-arn "arn:aws:redshift-serverless:us-east-1:123456789012:namespace/namespace-1"
  ```

  ここでは `rs-rp.json` に以下が含まれます。

------
#### [ JSON ]

****  

  ```
  {
  	"Version":"2012-10-17",		 	 	 
  	"Statement": [
  		{
  			"Effect": "Allow",
  			"Principal": {
  				"Service": "redshift.amazonaws.com"
  			},
  			"Action": "redshift:AuthorizeInboundIntegration",
  			"Resource": "arn:aws:redshift-serverless:us-east-1:123456789012:namespace/namespace-1",
  			"Condition": {
  				"StringEquals": {
  					"aws:SourceArn": "arn:aws:s3:::amzn-s3-demo-bucket",
  					"aws:SourceAccount": 111122223333
  	
  				}
  			}
  		},
  		{
  			"Effect": "Allow",
  			"Principal": {
  				"AWS": "arn:aws:iam::123456789012:user/myUser"
  			},
  			"Action": "redshift:CreateInboundIntegration",
  			"Resource": "arn:aws:redshift-serverless:us-east-1:123456789012:namespace/namespace-1",
  			"Condition": {
  				"StringEquals": {
  					"aws:SourceArn": "arn:aws:s3:::amzn-s3-demo-bucket",
  					"aws:SourceAccount": 111122223333
  				}
  			}
  		}
  	]
  }
  ```

------

## S3 イベント統合を作成する
<a name="loading-data-copy-job-create-s3-event-integration"></a>

コピージョブを設定するには、まず、S3 イベント統合を定義します。

------
#### [ Amazon Redshift console ]

**Amazon Redshift コンソールで Amazon S3 イベント統合を作成するには**

1. AWS マネジメントコンソール にサインインして、[https://console.aws.amazon.com/redshiftv2/](https://console.aws.amazon.com/redshiftv2/) で Amazon Redshift コンソールを開きます。

1. 左側のナビゲーションペインから、**[S3 イベント統合]** を選択します。

1. **[Amazon S3 イベント統合の作成]** を選択してウィザードを開き、自動コピーで使用する S3 イベント統合を作成します。ソースの Amazon S3 バケット とターゲットの Amazon Redshift データウェアハウスが同じ AWS リージョンにある必要があります。統合の作成ステップを進めながら、以下の情報を指定してください。
   + **統合名** – 現在の AWS リージョンにおいて AWS アカウントが所有するすべての統合を一意に区別するための識別子。
   + **説明** – 後から参照するために、Amazon S3 イベント統合について説明するテキスト。
   + **ソース S3 バケット** – 現在の AWS アカウント および AWS リージョンの Amazon S3 バケット。Amazon Redshift に取り込まれるデータの提供元 (ソース) です。
   + **Amazon Redshift データウェアハウス** - 統合を通じてデータを受け取るターゲットとなる、Amazon Redshift のプロビジョニング済みクラスターまたは Redshift Serverless のワークグループ。

     ターゲット Amazon Redshift が同じアカウントにある場合は、ターゲットを選択できます。ターゲットが別のアカウントにある場合は、**[Amazon Redshift データウェアハウスの ARN]** を指定してください。ターゲットには、認証済みのプリンシパルと統合ソースを指定したリソースポリシーも必要です。ターゲットに正しいリソースポリシーがなく、かつターゲットが同じアカウントにある場合は、**[修正する]** オプションを選択して、統合の作成プロセス中にリソースポリシーを自動的に適用できます。ターゲットが別の AWS アカウント にある場合は、Amazon Redshift ウェアハウスにリソースポリシーを手動で適用する必要があります。

1. 最大 50 個のタグ **[キー]** とオプションの **[値]** を入力します。これは、統合に関する追加のメタデータを提供します。

1. レビューページが表示されます。ここで、**[S3 イベント統合の作成]** を選択できます。

------
#### [ AWS CLI ]

AWS CLI を使用して Amazon S3 イベント統合を作成するには、以下のオプションを指定して `create-integration` コマンドを使用します。
+ `integration-name` — 統合の名前を指定します。
+ `source-arn` – ソースの Amazon S3 バケットの ARN を指定します。
+ `target-arn` - Amazon Redshift でプロビジョニングされたクラスターまたは Redshift Serverless ワークグループターゲットの名前空間 ARN を指定します。

次の例では、統合名、ソース ARN、ターゲット ARN を指定して統合を作成します。統合は暗号化されません。

```
aws redshift create-integration \
--integration-name s3-integration \
--source-arn arn:aws:s3:us-east-1::s3-example-bucket \
--target-arn arn:aws:redshift:us-east-1:123456789012:namespace:a1b2c3d4-5678-90ab-cdef-EXAMPLE22222
          {
    "IntegrationArn": "arn:aws:redshift:us-east-1:123456789012:integration:a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
    "IntegrationName": "s3-integration",
    "SourceArn": "arn:aws:s3:::s3-example-bucket",
    "SourceType": "s3-event-notifications",
    "TargetArn": "arn:aws:redshift:us-east-1:123456789012:namespace:a1b2c3d4-5678-90ab-cdef-EXAMPLE22222",
    "Status": "creating",
    "Errors": [],
    "CreateTime": "2024-10-09T19:08:52.758000+00:00",
    "Tags": []
}
```

次の AWS CLI コマンドを使用して、S3 イベント統合を管理することもできます。
+ `delete-integration` – 統合の ARN を指定して、S3 イベント統合を削除します。
+ `modify-integration` – 統合の ARN を指定して、S3 イベント統合の名前または説明 (またはその両方) を変更します。
+ `describe-integrations` – 統合の ARN を指定して、S3 イベント統合のプロパティを表示します。

これらのコマンドの詳細については、「[https://docs.aws.amazon.com/cli/latest/reference/redshift/](https://docs.aws.amazon.com/cli/latest/reference/redshift/)」を参照してください。

------

その後、関連するソースとターゲット、ステータス、関連付けられた自動コピージョブのステータスに関する情報を使用して、Amazon Redshift で S3 イベント統合が作成されます。Amazon Redshift コンソールで S3 イベント統合に関する情報を表示できます。**[S3 イベント統合]**を選択し、統合を選択すると、その詳細情報が表示されます。**[アカウント内]** で作成された統合と **[他のアカウントから]** 作成された統合は分けて表示されます。**[アカウント内]** リストには、ソースとターゲットが同一アカウントにある統合が表示されます。**[他のアカウントから]** リストには、ソースが別のアカウントによって所有されている統合が表示されます。

S3 イベント統合を削除すると、対応する COPY JOB のステータスが `1` (アクティブ) から `0` (非アクティブ/保留中) に変わります。ただし、対応する COPY JOB は自動的には削除されません。後で同じ名前の COPY JOB を作成しようとすると、競合が生じる可能性があります。

## COPY JOB を作成および監視する
<a name="loading-data-copy-job-create-s3-autocopy"></a>

統合が作成されたら、その統合の **[S3 イベント統合の詳細]** ページで、**[自動コピージョブの作成]** を選択して Amazon Redshift クエリエディタ v2 に移動し、統合の自動コピージョブを作成できます。Amazon Redshift は、COPY JOB CREATE ステートメントの FROM 句に指定されたバケットを、S3 イベント統合で使用されるバケットと一致させます。Amazon Redshift クエリエディタ v2 の使用方法については、「*Amazon Redshift 管理ガイド*」の「[Amazon Redshift クエリエディタ v2 を使用したデータベースのクエリの実行](https://docs.aws.amazon.com/redshift/latest/mgmt/query-editor-v2.html)」を参照してください。例えば、クエリエディタ v2 で次の COPY コマンドを実行して、Amazon S3 バケット `s3://amzn-s3-demo-bucket/staging-folder` を Amazon S3 イベント統合に対応付ける自動 COPY JOB を作成します。

```
COPY public.target_table
FROM 's3://amzn-s3-demo-bucket/staging-folder'
IAM_ROLE 'arn:aws:iam::123456789012:role/MyLoadRoleName'
JOB CREATE my_copy_job_name
AUTO ON;
```

COPY JOB は 1 回定義します。今後の実行でも同じパラメータが使用されます。

COPY JOB を定義および管理するには、アクセス許可が必要です。COPY JOB に対するアクセス許可の付与と取り消しについては、「[GRANT](r_GRANT.md)」および「[REVOKE](r_REVOKE.md)」を参照してください。COPY JOB の範囲指定のアクセス許可の付与と取り消しについては、「[スコープ付きアクセス許可の付与](r_GRANT.md#grant-scoped-syntax)」および「[スコープ付きアクセス許可の取り消し](r_REVOKE.md#revoke-scoped-permissions)」を参照してください。

CREATE、LIST、SHOW、DROP、ALTER、RUN の各ジョブのオプションを使用して、ロード操作を管理します。詳細については、「[COPY JOB](r_COPY-JOB.md)」を参照してください。

システムビューにクエリを実行して、COPY JOB のステータスと進行状況を確認できます。ビューは次のように表示されます。
+ [SYS\$1COPY\$1JOB](SYS_COPY_JOB.md) — 現在定義されている各 COPY JOB の行が含まれます。
+ [SYS\$1COPY\$1JOB\$1DETAIL](SYS_COPY_JOB_DETAIL.md) – COPY JOB ごとに、ファイルの取り込みが保留中、エラー、または取り込み完了かについての詳細情報が含まれています。
+ [SYS\$1COPY\$1JOB\$1INFO](SYS_COPY_JOB_INFO.md) – COPY JOB についてログに記録されたメッセージが含まれています。
+ [SYS\$1LOAD\$1HISTORY](SYS_LOAD_HISTORY.md) — COPY コマンドの詳細が含まれます。
+ [SYS\$1LOAD\$1ERROR\$1DETAIL](SYS_LOAD_ERROR_DETAIL.md) — COPY コマンドエラーの詳細が含まれます。
+ [SVV\$1COPY\$1JOB\$1INTEGRATIONS](SVV_COPY_JOB_INTEGRATIONS.md) – S3 イベント統合の詳細情報が含まれています。
+ [STL\$1LOAD\$1ERRORS](r_STL_LOAD_ERRORS.md) — COPY コマンドのエラーが含まれます。
+ [STL\$1LOAD\$1COMMITS](r_STL_LOAD_COMMITS.md) — COPY コマンドのデータロードのトラブルシューティングに使用される情報が含まれます。

S3 イベント統合エラーのトラブルシューティングの詳細については、「[S3 イベント統合と COPY JOB のエラーのトラブルシューティング](s3-integration-troubleshooting.md)」を参照してください。

COPY JOB でロードされたファイルのリストを取得するには、次の SQL を実行します。最初に *<job\$1id>* を置き換えてください。

```
SELECT job_id, job_name, data_source, copy_query, filename, status, curtime
FROM sys_copy_job copyjob
JOIN stl_load_commits loadcommit
ON copyjob.job_id = loadcommit.copy_job_id
WHERE job_id = <job_id>;
```

## 自動コピー用の S3 イベント統合を作成する場合の考慮事項
<a name="loading-data-copy-job-considerations"></a>

自動コピーを使用する場合は、以下の点を考慮してください。
+ 1 つの AWS アカウントでは、クラスターまたはワークグループごとに最大 200 件の COPY JOB を作成できます。
+ Amazon Redshift ターゲットごとに最大 50 個の S3 イベント統合を作成できます。
+ バケット名にピリオド (.) が含まれるソース Amazon S3 バケットを使用して、S3イベント統合を作成することはできません。
+ 同じソースとターゲットの間に作成できる S3 イベント統合は 1 つのみです。つまり、Amazon S3 バケットと Amazon Redshift データウェアハウスの間では、一度に 1 つの S3 イベント統合しか作成できません。
+ ソース Amazon S3 バケットで定義されているイベントタイプ `S3_OBJECT_CREATED` の既存のイベント通知は利用できません。ただし、S3 イベント統合を作成した後に、より狭い範囲のプレフィックスまたはサフィックスを使用して、Amazon S3 バケットイベント通知を更新することができます。この方法の場合、他のターゲットに別のプレフィックスまたはサフィックスの `S3_OBJECT_CREATED` を設定して、S3 イベント統合との競合を回避することもできます。自動コピーが期待どおりに実行されない問題が発生した場合は、AWS サポート に問い合わせる際に、該当する期間の S3 バケットの `s3:PutBucketNotificationConfiguration` アクションの AWS CloudTrail ログを準備してください。

## サポート対象のリージョン
<a name="loading-data-copy-job-regions"></a>

以下のリージョンでは、自動コピーが利用できます。


| リージョン | 自動コピー | 
| --- | --- | 
| アフリカ (ケープタウン) | Available | 
| アジアパシフィック (香港) | Available | 
| アジアパシフィック (台北) | Available | 
| アジアパシフィック (東京) | Available | 
| アジアパシフィック (ソウル) | Available | 
| アジアパシフィック (大阪) | Available | 
| アジアパシフィック (ムンバイ) | Available | 
| アジアパシフィック (ハイデラバード) | Available | 
| アジアパシフィック (シンガポール) | Available | 
| アジアパシフィック (シドニー) | Available | 
| アジアパシフィック (ジャカルタ) | Available | 
| アジアパシフィック (メルボルン) | Available | 
| アジアパシフィック (マレーシア) | Available | 
| アジアパシフィック (ニュージーランド) | 利用不可 | 
| アジアパシフィック (タイ) | Available | 
| カナダ (中部) | Available | 
| カナダ西部 (カルガリー) | Available | 
| 中国 (北京) | Available | 
| 中国 (寧夏) | Available | 
| 欧州 (フランクフルト) | Available | 
| 欧州 (チューリッヒ) | Available | 
| 欧州 (ストックホルム) | Available | 
| 欧州 (ミラノ) | Available | 
| 欧州 (スペイン) | Available | 
| 欧州 (アイルランド) | Available | 
| 欧州 (ロンドン) | Available | 
| 欧州 (パリ) | Available | 
| イスラエル (テルアビブ) | Available | 
| 中東 (アラブ首長国連邦) | Available | 
| 中東 (バーレーン) | Available | 
| メキシコ (中部) | Available | 
| 南米 (サンパウロ) | Available | 
| 米国東部 (バージニア北部) | Available | 
| 米国東部 (オハイオ) | Available | 
| 米国西部 (北カリフォルニア) | Available | 
| 米国西部 (オレゴン) | Available | 
| AWS GovCloud (米国東部) | Available | 
| AWS GovCloud (米国西部) | Available | 

# DML コマンドによるテーブルのロード
<a name="t_Updating_tables_with_DML_commands"></a>

Amazon Redshift は、テーブルの行の変更に利用できる標準のデータ操作言語 (DML) コマンド (INSERT、UPDATE、DELETE) をサポートします。TRUNCATE コマンドを使用し、高速一括削除を実行することもできます。

**注記**  
大量のデータをロードする場合は [COPY](r_COPY.md) コマンドを使用することを強くお勧めします。個々に INSERT ステートメントを使ってテーブルにデータを入力すると著しく時間がかかる場合があります。または、他の Amazon Redshift データベーステーブルにデータが既に存在する場合、パフォーマンスを向上させるには INSERT INTO ... SELECT FROM または CREATE TABLE AS を使用します。詳細については、「[INSERT](r_INSERT_30.md)」または「[CREATE TABLE AS](r_CREATE_TABLE_AS.md)」を参照してください。

テーブルで行を挿入、更新、削除するとき、それが変更前と比較して相当な数になる場合、完了時にテーブルに ANALYZE および VACUUM コマンドを実行します。アプリケーションの小さな変更の数が時間とともに累積される場合、定期的に ANALYZE および VACUUM コマンドを実行するように日程を計画することもできます。詳細については、「[テーブルを分析する](t_Analyzing_tables.md)」および「[テーブルのバキューム処理](t_Reclaiming_storage_space202.md)」を参照してください。

**Topics**
+ [新しいデータの更新と挿入](t_updating-inserting-using-staging-tables-.md)

# 新しいデータの更新と挿入
<a name="t_updating-inserting-using-staging-tables-"></a>

MERGE コマンドを使用すると、既存のテーブルに新しいデータを効率的に追加できます。マージ操作を実行するには、ステージングテーブルを作成し、このセクションで説明している方法のいずれかを使用して、ステージングテーブルからターゲットテーブルを更新します。MERGE コマンドの詳細については、「[MERGE](r_MERGE.md)」を参照してください。

[マージの例](merge-examples.md) は、Amazon Redshift 用のサンプルデータセット (TICKIT データセット) を使用します。前提条件として、「[一般的なデータベースタスクの開始方法](https://docs.aws.amazon.com/redshift/latest/gsg/database-tasks.html)」に記載されている手順に従って、TICKIT テーブルとデータを設定できます。サンプルデータセットの詳細については、「[サンプルデータベース](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html)」を参照してください。

## マージ方法 1: 既存の行を置き換える
<a name="merge-method-replace-existing-rows"></a>

ターゲットテーブルのすべての列を上書きする場合、マージを実行する最速の方法は、既存の行を置き換えることです。これは、内部結合を使用して更新される行を削除するため、ターゲットテーブルを 1 回だけスキャンします。行は削除されると、1 回の挿入オペレーションによってステージングテーブルの新しい行と置き換えられます。

この方法は、以下の条件のすべてに該当する場合に使用してください。
+ ターゲットテーブルとステージングテーブルに同じ列が含まれる。
+ ターゲットテーブルの列のデータをすべて、ステージングテーブルの列で置き換えることを予定している。
+ マージでステージングテーブルの行をすべて使用する。

ここに挙げた条件のなかに当てはまらないものがあった場合は、次のセクションで説明する「マージ方法 2: MERGE を使用せずに列リストを指定する」を使用します。

ステージングテーブルの行すべてを使用するわけではない場合には、DELETE ステートメントおよび INSERT ステートメントに WHERE 句を使用して、変更がない行を除外します。ただし、マージでステージングテーブルの行の大部分を使用しない場合には、このセクションで後ほど説明するように UPDATE と INSERT を別個に実行する方法を推奨しています。

## マージ方法 2: MERGE を使用せずに列リストを指定する
<a name="merge-method-specify-column-list"></a>

行全体を上書きするのではなく、テーブルの特定の列を更新する場合には、この方法を使用します。この方法では、更新のステップを追加する必要があり、MERGE コマンドを使用しないため、前の方法よりも時間がかかります。このため、以下の条件のいずれかに該当する場合にこの方法を使用してください。
+ テーブルの列すべてを更新するわけではない。
+ 更新でステージングテーブルの行のほとんどを使用しない。

**Topics**
+ [マージ方法 1: 既存の行を置き換える](#merge-method-replace-existing-rows)
+ [マージ方法 2: MERGE を使用せずに列リストを指定する](#merge-method-specify-column-list)
+ [一時的に使用するステージングテーブルを作成する](merge-create-staging-table.md)
+ [既存の行を置き換えてマージ操作を実現する](merge-replacing-existing-rows.md)
+ [MERGE コマンドを使用せずに列リストを指定してマージ操作を実行する](merge-specify-a-column-list.md)
+ [マージの例](merge-examples.md)

# 一時的に使用するステージングテーブルを作成する
<a name="merge-create-staging-table"></a>

*ステージングテーブル*は、*ターゲットテーブル*を変更 (更新、挿入含む) する際に使用するデータすべてを一時的に保持するためのテーブルです。

マージ操作では、ステージングテーブルとターゲットテーブルを結合する必要があります。結合する列をコロケーションするには、ステージングテーブルの分散キーを、ターゲットテーブルの分散キーと同じ列に設定する必要があります。例えば、ターゲットテーブルが分散キー列に外部キーを使用している場合には、ステージングテーブルの分散キーと同じ列を使用する必要があります。[CREATE TABLE LIKE](r_CREATE_TABLE_NEW.md#create-table-like) ステートメントを使用してステージングテーブルを作成すると、ステージングテーブルが親テーブルから分散キーを継承します。CREATE TABLE AS ステートメントを使用する場合、新しいテーブルは分散キーを継承しません。詳細については、「[クエリ最適化のためのデータのディストリビューション](t_Distributing_data.md)」を参照してください。

分散キーがプライマリキーと異なり、マージ操作の一環として分散キーが更新されない場合には、分散キー列の冗長結合述語を追加し、コロケーテッド結合を実現します。次に例を示します。

```
where target.primarykey = stage.primarykey 
and target.distkey = stage.distkey
```

クエリでコロケーテッド結合を使用するかどうかを確認するには、[EXPLAIN](r_EXPLAIN.md) を使用してクエリを実行し、結合すべてに DS\$1DIST\$1NONE があるかどうかを確認します。詳細については、「[クエリプランの評価](c_data_redistribution.md)」を参照してください。

# 既存の行を置き換えてマージ操作を実現する
<a name="merge-replacing-existing-rows"></a>

手順で説明しているマージオペレーションを実行するときは、一時的なステージングテーブルの作成と削除のステップを除き、すべてのステップを 1 つのトランザクションにまとめます。いずれかのステップが失敗した場合でも、トランザクションはロールバックされます。トランザクションを 1 つにすると、他にもコミットの回数が減るため、時間とリソースの節約になります。

**既存の行を置き換えてマージ操作を実現するには、以下の手順を実行します。**

1. 次の疑似コードに示すように、ステージングテーブルを作成し、マージの対象となるデータを移します。

   ```
   CREATE temp table stage (like target); 
   
   INSERT INTO stage 
   SELECT * FROM source 
   WHERE source.filter = 'filter_expression';
   ```

1.  MERGE を使用してステージングテーブルとの内部結合を実行し、ステージングテーブルと一致するターゲットテーブルの行を更新します。次に、ステージングテーブルと一致しない残りのすべての行をターゲットテーブルに挿入します。

    更新と挿入の操作は 1 つの MERGE コマンドで実行することをお勧めします。

   ```
   MERGE INTO target 
   USING stage [optional alias] on (target.primary_key = stage.primary_key)
   WHEN MATCHED THEN 
   UPDATE SET col_name1 = stage.col_name1 , col_name2= stage.col_name2, col_name3 = {expr}
   WHEN NOT MATCHED THEN
   INSERT (col_name1 , col_name2, col_name3) VALUES (stage.col_name1, stage.col_name2, {expr});
   ```

1. ステージングテーブルを削除 (Drop) します。

   ```
   DROP TABLE stage;
   ```

# MERGE コマンドを使用せずに列リストを指定してマージ操作を実行する
<a name="merge-specify-a-column-list"></a>

手順で説明しているマージオペレーションを実行するときは、すべてのステップを 1 つのトランザクションにまとめます。いずれかのステップが失敗した場合でも、トランザクションはロールバックされます。トランザクションを 1 つにすると、他にもコミットの回数が減るため、時間とリソースの節約になります。

**列リストを指定してマージ操作を実行するには、以下の手順を実行します。**

1. 操作全体を 1 つのトランザクションブロックにまとめます。

   ```
   BEGIN transaction;
   … 
   END transaction;
   ```

1. 次の疑似コードに示すように、ステージングテーブルを作成し、マージの対象となるデータを移します。

   ```
   create temp table stage (like target); 
   insert into stage 
   select * from source 
   where source.filter = 'filter_expression';
   ```

1. ステージングテーブルで内部結合を使用して、ターゲットテーブルを更新します。
   + UPDATE 句で、更新の対象となる列を明示的にリストします。
   + ステージングテーブルで内部結合を実行します。
   + 分散キーがプライマリキーと異なり、分散キーが更新の対象でない場合は、冗長結合を分散キーに追加します。クエリでコロケーテッド結合を使用するかどうかを確認するには、[EXPLAIN](r_EXPLAIN.md) を使用してクエリを実行し、結合すべてに DS\$1DIST\$1NONE があるかどうかを確認します。詳細については、「[クエリプランの評価](c_data_redistribution.md)」を参照してください。
   + ターゲットテーブルがタイムスタンプでソートされる場合、述語を追加し、ターゲットテーブルの範囲限定スキャンを活用します。詳細については、「[Amazon Redshift クエリの設計のベストプラクティス](c_designing-queries-best-practices.md)」を参照してください。
   + マージですべての行を使用しない場合は、句を追加して、変更する行をフィルタリングします。例えば、1 つ以上の列に不等フィルタを追加して、変更されていない列を除外します。
   + 問題が発生した場合に全体をロールバックできるよう、更新操作、削除操作、挿入操作を単一のトランザクションにまとめます。

    次に例を示します。

   ```
   begin transaction;
   
   update target 
   set col1 = stage.col1, 
   col2 = stage.col2, 
   col3 = 'expression' 
   from stage 
   where target.primarykey = stage.primarykey 
   and target.distkey = stage.distkey 
   and target.col3 > 'last_update_time' 
   and (target.col1 != stage.col1 
   or target.col2 != stage.col2 
   or target.col3 = 'filter_expression');
   ```

1. ターゲットテーブルで内部結合を使用して、ステージングテーブルから不要になった行を削除します。ターゲットテーブルの一部の行はすでにステージングテーブルの対応する行に一致し、その他は前のステップで更新されました。どちらの場合も、挿入のために必要ありません。

   ```
   delete from stage 
   using target 
   where stage.primarykey = target.primarykey;
   ```

1. ステージングテーブルから残りの行を挿入します。ステップ 2 の UPDATE ステートメントで使用した列リストと同じものを VALUES 句内で使用します。

   ```
   insert into target
   (select col1, col2, 'expression'
   from stage);
   
   end transaction;
   ```

1. ステージングテーブルを削除 (Drop) します。

   ```
   drop table stage;
   ```

# マージの例
<a name="merge-examples"></a>

以下の例では、マージを実行して SALES テーブルを更新します。最初の例では、ターゲットテーブルから削除した後でステージングテーブルからすべての行を挿入する、よりシンプルな方法を使用しています。2 番目の例では、ターゲットテーブル内の選択した列の更新が必要であるため、追加の更新ステップが含まれています。

[マージの例](#merge-examples) は、Amazon Redshift 用のサンプルデータセット (TICKIT データセット) を使用します。前提条件として、「[一般的なデータベースタスクの開始方法](https://docs.aws.amazon.com/redshift/latest/gsg/database-tasks.html)」ガイドの手順に従って、TICKIT テーブルとデータを設定できます。サンプルデータセットの詳細については、「[サンプルデータベース](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html)」を参照してください。

**マージデータソースのサンプル**

このセクションの例では、更新と挿入を両方とも含んでいるサンプル データソースが必要です。これらの例では、SALES テーブルからのデータを使用する SALES\$1UPDATE というサンプルテーブルを作成します。12 月の新しい販売アクティビティを表すランダムデータを新しいテーブルに入力します。SALES\$1UPDATE サンプルテーブルを使用して、ステージングテーブルを以下の例で作成します。

```
-- Create a sample table as a copy of the SALES table.

create table tickit.sales_update as
select * from tickit.sales;

-- Change every fifth row to have updates.

update tickit.sales_update
set qtysold = qtysold*2,
pricepaid = pricepaid*0.8,
commission = commission*1.1
where saletime > '2008-11-30'
and mod(sellerid, 5) = 0;

-- Add some new rows to have inserts.
-- This example creates a duplicate of every fourth row.

insert into tickit.sales_update
select (salesid + 172456) as salesid, listid, sellerid, buyerid, eventid, dateid, qtysold, pricepaid, commission, getdate() as saletime
from tickit.sales_update
where saletime > '2008-11-30'
and mod(sellerid, 4) = 0;
```

**マッチングキーに基づいて既存の行を置き換えるマージの例**

以下のスクリプトでは、SALES\$1UPDATE テーブルを使用して、12 月の販売アクティビティの新しいデータによる SALES テーブルでのマージ操作を実行します。この例では、SALES テーブルの更新がある行を置き換えます。この例では、qtysold 列と pricepaid 列を更新しますが、commission と saletime は変更しません。

```
MERGE into tickit.sales 
USING tickit.sales_update sales_update  
on ( sales.salesid = sales_update.salesid
and sales.listid = sales_update.listid
and sales_update.saletime > '2008-11-30'
and (sales.qtysold != sales_update.qtysold 
or sales.pricepaid != sales_update.pricepaid))
WHEN MATCHED THEN
update SET qtysold = sales_update.qtysold,
pricepaid = sales_update.pricepaid
WHEN NOT MATCHED THEN 
INSERT (salesid, listid, sellerid, buyerid, eventid, dateid, qtysold , pricepaid, commission, saletime)
values (sales_update.salesid, sales_update.listid, sales_update.sellerid, sales_update.buyerid, sales_update.eventid, 
sales_update.dateid, sales_update.qtysold , sales_update.pricepaid, sales_update.commission, sales_update.saletime);

-- Drop the staging table.
drop table tickit.sales_update;

-- Test to see that commission and salestime were not impacted.
SELECT sales.salesid, sales.commission, sales.salestime, sales_update.commission, sales_update.salestime 
FROM tickit.sales 
INNER JOIN tickit.sales_update sales_update  
ON 
sales.salesid = sales_update.salesid
AND sales.listid = sales_update.listid
AND sales_update.saletime > '2008-11-30'
AND (sales.commission != sales_update.commission 
OR sales.salestime != sales_update.salestime);
```

**MERGE を使用せずに列リストを指定するマージの例**

以下の例では、12 月の販売アクティビティの新しいデータで SALES を更新するマージ操作を実行します。更新と挿入の両方を含み、変更されていない行を含む、サンプルデータが必要です。この例では、QTYSOLD および PRICEPAID 列を更新し、COMMISSION および SALETIME は変更しません。以下のスクリプトでは、SALES\$1UPDATE テーブルを使用して、SALES テーブルでのマージ操作を実行しています。

```
-- Create a staging table and populate it with rows from SALES_UPDATE for Dec
create temp table stagesales as select * from sales_update
where saletime > '2008-11-30';

-- Start a new transaction
begin transaction;

-- Update the target table using an inner join with the staging table
-- The join includes a redundant predicate to collocate on the distribution key –- A filter on saletime enables a range-restricted scan on SALES

update sales
set qtysold = stagesales.qtysold,
pricepaid = stagesales.pricepaid
from stagesales
where sales.salesid = stagesales.salesid
and sales.listid = stagesales.listid
and stagesales.saletime > '2008-11-30'
and (sales.qtysold != stagesales.qtysold 
or sales.pricepaid != stagesales.pricepaid);
 
-- Delete matching rows from the staging table 
-- using an inner join with the target table

delete from stagesales
using sales
where sales.salesid = stagesales.salesid
and sales.listid = stagesales.listid;

-- Insert the remaining rows from the staging table into the target table
insert into sales
select * from stagesales;

-- End transaction and commit
end transaction;

-- Drop the staging table
drop table stagesales;
```

# ディープコピーを実行する
<a name="performing-a-deep-copy"></a>

ディープコピーでは、テーブルを自動的にソートする一括挿入を利用してテーブルを再作成し、データを入力します。テーブルにソートされていない大規模なリージョンがある場合、ディープコピーの方がバキューム処理より高速です。ディープコピーオペレーション中の同時更新は、追跡可能な場合にのみ行うことをお勧めします。プロセスが完了したら、差分更新を新しいテーブルに移動します。VACUUM オペレーションは同時更新を自動でサポートします。

以下のいずれかの方法を選択し、元のテーブルのコピーを作成できます。
+ 元のテーブル DDL を使用します。

  CREATE TABLE DDL が利用できる場合、これが最も速く推奨の方法になります。新しいテーブルを作成する場合は、プライマリキーと外部キーを含むすべてのテーブルと列の属性を指定できます。SHOW TABLE 関数を使用すると、元の DDL を検索できます。
+ CREATE TABLE LIKE を使用します。

  元の DDL が利用できない場合、CREATE TABLE LIKE を使用して元のテーブルを再作成できます。新しいテーブルは親テーブルのエンコーディング、分散キー、ソートキー、非 null の属性を継承します。新しいテーブルは親テーブルのプライマリキーと外部キーの属性を継承しませんが、[ALTER TABLE](r_ALTER_TABLE.md) を使ってそれらを追加できます。
+ 一時テーブルを作成し、元のテーブルの全データを削除します。

  親テーブルのプライマリキーおよび外部キーの属性を保持する必要がある場合。親テーブルに依存関係がある場合は、CREATE TABLE... を使用できます。AS (CTAS) を使って一時テーブルを作成します。次に、元のテーブルの全データを削除してから、一時テーブルのデータを入力します。

  一時テーブルを使用すると、永続テーブルを使用する場合と比較して著しくパフォーマンスが向上しますが、データを失うリスクがあります。一時テーブルは、作成したセッションの終了時に自動的に削除されます。TRUNCATE を使うと、トランザクションブロック内にある場合でも、即座にコミットされます。TRUNCATE が成功しても後続の INSERT が完了する前にシャットダウンした場合、データが失われます。データ損失を許容できない場合は、永続テーブルを使用します。

テーブルのコピーを作成した後、新しいテーブルへのアクセスを許可する必要がある場合があります。[GRANT](r_GRANT.md) を使用してアクセス権限を定義できます。テーブルのすべてのアクセス権限を表示および付与するには、次のいずれかに該当する必要があります。
+  スーパーユーザー。
+  コピーするテーブルの所有者。
+  テーブルの権限を確認するための ACCESS SYSTEM TABLE 権限と、関連するすべての権限の付与権限を持つユーザー。

さらに、ディープコピーが格納されているスキーマの使用権限を付与する必要がある場合があります。ディープコピーのスキーマが元のテーブルのスキーマと異なり、また `public` スキーマでもない場合は、使用権限を付与する必要があります。使用権限を表示および付与するには、次のいずれかに該当する必要があります。
+  スーパーユーザー。
+  ディープコピーのスキーマに対する USAGE 権限を付与できるユーザー。

**元のテーブル DDL を使用してディープコピーを実行するには、次のように実行します。**

1. (オプション) `v_generate_tbl_ddl` というスクリプトを実行してテーブル DDL を再作成します。

1. 元の CREATE TABLE DDL を使い、テーブルのコピーを作成します。

1. INSERT INTO … SELECT ステートメントを使い、元のテーブルのデータをコピーに入力します。

1. 古いテーブルに付与されている権限を確認してください。これらの権限は、SVV\$1RELATION\$1PRIVILEGES システムビューで確認できます。

1. 必要に応じて、古いテーブルの権限を新しいテーブルに付与します。

1. 元のテーブルで権限を持つすべてのグループとユーザーに使用権限を付与します。ディープコピーテーブルが `public` スキーマ内にある場合、または元のテーブルと同じスキーマにある場合は、この手順は必要ありません。

1. 元のテーブルを削除 (Drop) します。

1. ALTER TABLE ステートメントを使用し、コピーの名前を元のテーブル名に変更します。

次の例では、sample\$1copy という名前の SAMPLE の複製を利用し、SAMPLE テーブルにディープコピーを実行します。

```
--Create a copy of the original table in the sample_namespace namespace using the original CREATE TABLE DDL.
create table sample_namespace.sample_copy ( … );

--Populate the copy with data from the original table in the public namespace.
insert into sample_namespace.sample_copy (select * from public.sample);

--Check SVV_RELATION_PRIVILEGES for the original table's privileges.
select * from svv_relation_privileges where namespace_name = 'public' and relation_name = 'sample' order by identity_type, identity_id, privilege_type;

--Grant the original table's privileges to the copy table.
grant DELETE on table sample_namespace.sample_copy to group group1;
grant INSERT, UPDATE on table sample_namespace.sample_copy to group group2;
grant SELECT on table sample_namespace.sample_copy to user1;
grant INSERT, SELECT, UPDATE on table sample_namespace.sample_copy to user2;
         
--Grant usage permission to every group and user that has privileges in the original table.
grant USAGE on schema sample_namespace to group group1, group group2, user1, user2;

--Drop the original table.
drop table public.sample;

--Rename the copy table to match the original table's name.
alter table sample_namespace.sample_copy rename to sample;
```

**CREATE TABLE LIKE を使用してディープコピーを実行するには、次のように実行します。**

1. CREATE TABLE LIKE を使用して新しいテーブルを作成します。

1. INSERT INTO … SELECT ステートメントを使用し、現在のテーブルから新しいテーブルに行をコピーします。

1. 古いテーブルに付与されている権限を確認してください。これらの権限は、SVV\$1RELATION\$1PRIVILEGES システムビューで確認できます。

1. 必要に応じて、古いテーブルの権限を新しいテーブルに付与します。

1. 元のテーブルで権限を持つすべてのグループとユーザーに使用権限を付与します。ディープコピーテーブルが `public` スキーマ内にある場合、または元のテーブルと同じスキーマにある場合は、この手順は必要ありません。

1. 現在のテーブルを削除 (Drop) します。

1. ALTER TABLE ステートメントを使用し、新しいテーブルの名前を元のテーブル名に変更します。

次の例では、CREATE TABLE LIKE を使用して SAMPLE テーブルにディープコピーを実行します。

```
--Create a copy of the original table in the sample_namespace namespace using CREATE TABLE LIKE.
create table sameple_namespace.sample_copy (like public.sample);

--Populate the copy with data from the original table.
insert into sample_namespace.sample_copy (select * from public.sample);

--Check SVV_RELATION_PRIVILEGES for the original table's privileges.
select * from svv_relation_privileges where namespace_name = 'public' and relation_name = 'sample' order by identity_type, identity_id, privilege_type;

--Grant the original table's privileges to the copy table.
grant DELETE on table sample_namespace.sample_copy to group group1;
grant INSERT, UPDATE on table sample_namespace.sample_copy to group group2;
grant SELECT on table sample_namespace.sample_copy to user1;
grant INSERT, SELECT, UPDATE on table sample_namespace.sample_copy to user2;
         
--Grant usage permission to every group and user that has privileges in the original table.
grant USAGE on schema sample_namespace to group group1, group group2, user1, user2;

--Drop the original table.
drop table public.sample;

--Rename the copy table to match the original table's name.
alter table sample_namespace.sample_copy rename to sample;
```

**一時テーブルを作成し、元のテーブルの全データを削除する方法でディープコピーを実行するには、次のように実行します。**

1. CREATE TABLE AS を使用し、元のテーブルの行を使用して一時テーブルを作成します。

1. 現在のテーブルの全データを削除します。

1. INSERT INTO … SELECT ステートメントを使用し、一時テーブルから元のテーブルに行をコピーします。

1. 一時テーブルを削除 (Drop) します。

次の例では、一時テーブルを作成し、元のテーブルの全データを削除することによって、SALES テーブルにディープコピーが実行されます。元のテーブルはそのまま残っているため、コピーテーブルにアクセス権限を付与する必要はありません。

```
--Create a temp table copy using CREATE TABLE AS.
create temp table salestemp as select * from sales;

--Truncate the original table.
truncate sales;

--Copy the rows from the temporary table to the original table.
insert into sales (select * from salestemp);

--Drop the temporary table.
drop table salestemp;
```

# テーブルを分析する
<a name="t_Analyzing_tables"></a>

ANALYZE オペレーションは、クエリプランナーで最適な計画の選択に使用される統計メタデータを更新します。

多くの場合、ANALYZE コマンドを明示的に実行する必要はありません。Amazon Redshift は、ワークロードの変更をモニタリングし、統計をバックグラウンドで自動的に更新します。さらに、COPY コマンドは空のテーブルにデータをロードした際に分析を自動で実行します。

テーブルまたはデータベース全体を明示的に分析するには、[ANALYZE](r_ANALYZE.md) コマンドを実行します。

## 自動分析
<a name="t_Analyzing_tables-auto-analyze"></a>

Amazon Redshift はデータベースを継続的にモニタリングし、バックグラウンドで自動的に分析オペレーションを実行します。システムパフォーマンスへの影響を最小限にするために、自動分析はワークロードが軽い期間に実行されます。

自動分析はデフォルトで有効になっています。自動分析を無効にするには、クラスターのパラメータグループを変更して `auto_analyze` パラメータを **false** に設定します。

処理時間を短縮し、システムの全体的なパフォーマンスを向上させるために、Amazon Redshift は、変更の程度が低いテーブルの自動分析を省略します。

分析オペレーションは、最新の統計を含むテーブルを省略します。抽出およびロード (ETL) ワークフローの一環として ANALYZE を実行する場合、自動分析は最新の統計を含むテーブルを省略します。同様に、自動分析によりテーブルの統計が更新された場合、明示的な ANALYZE はテーブルを省略します。

## 新しいテーブルデータの分析
<a name="t_Analyzing_tables-new-tables"></a>

 デフォルトでは、COPY コマンドは空のテーブルにデータをロードした後に ANALYZE を実行します。STATUPDATE を ON に設定すれば、テーブルが空であるかどうかに関係なく、ANALYZE を強制できます。STATUPDATE に OFF を指定した場合、ANALYZE は実行されません。テーブルの所有者とスーパーユーザーのみが ANALYZE コマンドまたは STATUPDATE を ON に設定した COPY コマンドを実行できます。

Amazon Redshift では、以下のコマンドを使用して作成したテーブルが分析されます。
+ CREATE TABLE AS (CTAS) 
+ CREATE TEMP TABLE AS 
+ SELECT INTO 

データの初回ロード後に分析されなかった新しいテーブルにクエリを実行する場合、Amazon Redshift は警告メッセージを返します。その後の更新またはロードの後にテーブルにクエリを実行しても警告は発生しません。分析されていないテーブルを参照するクエリに EXPLAIN コマンドを実行すると、同じ警告メッセージが返されます。

データを空ではないテーブルに追加するとテーブルのサイズが大きく変化する場合はいつでも、統計を明示的に更新することができます。これは、ANALYZE コマンドを実行するか、STATUPDATE オプションを ON にした COPY コマンドを使用することで実行できます。最後の ANALYZE 以降に挿入または削除された行数の詳細を表示するには、[PG\$1STATISTIC\$1INDICATOR](r_PG_STATISTIC_INDICATOR.md) システムカタログテーブルに対してクエリを実行します。

[ANALYZE](r_ANALYZE.md) コマンドの範囲を次のいずれかに指定できます。
+ 現在のデータベース全体
+ 1 つのテーブル
+ 1 つのテーブルの 1 つまたは複数の特定の列
+ クエリの述語として使用される可能性が高い列

 ANALYZE コマンドを実行すると、テーブルからサンプルの行が取得され、いくつかの計算が行われ、結果的に生成される列の統計が保存されます。デフォルトでは、Amazon Redshift は DISTKEY 列にサンプルパスを実行し、テーブルのその他すべての列に別のサンプルパスを実行します。列のサブセットの統計を生成するには、カンマ区切りの列リストを指定します。PREDICATE COLUMNS 句を使用して ANALYZE を実行して、述語として使用されていない列を省略できます。

 ANALYZE 操作はリソースを集中的に使います。そのため、実際に統計更新を必要とするテーブルと列にのみ実行します。定期的に、または同じスケジュールですべてのテーブルのすべての行を分析する必要はありません。データが大幅に変更される場合、次で頻繁に使用される列を分析します。
+ ソートおよびグループ化の操作
+ 結合
+ クエリ述語

処理時間を短縮し、システム全体のパフォーマンスを向上させるために、Amazon Redshift は、変更された行の割合が低いテーブルの ANALYZE をスキップします。この動作は [analyze\$1threshold\$1percent](r_analyze_threshold_percent.md) パラメータで決定されます。デフォルトでは、分析のしきい値は 10 パーセントに設定されます。[SET](r_SET.md) コマンドを実行して、現在のセッションの分析しきい値を変更できます。

頻繁に分析する必要のない列は、大きな VARCHAR 列など、実際に問い合わされることがない事実、単位、関連属性を表す列です。例えば、TICKIT データベースの LISTING テーブルについて考えてみます。

```
select "column", type, encoding, distkey, sortkey
from pg_table_def where tablename = 'listing';


column         |        type        | encoding | distkey | sortkey 
---------------+--------------------+----------+---------+---------
listid         | integer            | none     | t       | 1       
sellerid       | integer            | none     | f       | 0       
eventid        | integer            | mostly16 | f       | 0       
dateid         | smallint           | none     | f       | 0       
numtickets     | smallint           | mostly8  | f       | 0       
priceperticket | numeric(8,2)       | bytedict | f       | 0       
totalprice     | numeric(8,2)       | mostly32 | f       | 0       
listtime       | timestamp with...  | none     | f       | 0
```

このテーブルに大量の新しいレコードが毎日ロードされる場合、結合キーとしてクエリで頻繁に使用される LISTID 列を定期的に分析する必要があります。TOTALPRICE と LISTTIME が頻繁に使用されるクエリの制約である場合、平日は毎日、それらの列と分散キーを分析できます。

```
analyze listing(listid, totalprice, listtime);
```

アプリケーションの販売者とイベントが非常に静的であり、日付 ID がわずか 2 年または 3 年をカバーする固定日数セットを参照するとします。この場合、これらの列の一意の値は大きく変更されません。ただし、一意の各値のインスタンス数は着実に増加します。

さらに、NUMTICKETS および PRICEPERTICKET メジャーが TOTALPRICE 列とまれに比較され、クエリされるという場合を考えてみてください。この場合、毎週末に 1 回、テーブル全体で ANALYZE コマンドを実行して、毎日分析されていない 5 つの列の統計を更新することができます。
<a name="t_Analyzing_tables-predicate-columns"></a>
**述語列**  
列リストを指定する、便利な代替方法として、述語として使用される可能性が高い列のみを分析するように選択できます。クエリを実行すると、結合、フィルタ条件、または GROUP BY 句で使用される列は、システムカタログの述語列としてマークされます。PREDICATE COLUMNS 句を指定して ANALYZE を実行すると、ANALYZE 操作には次の基準を満たす列のみが含まれます。
+ 列は述語列としてマークされます。
+ 列が分散キーです。
+ 列はソートキーの一部です。

表の列のいずれも述部としてマークされていない場合、PREDICATE COLUMNS が指定されていても、ANALYZE にはすべての列が含まれます。述語の列としてマークされている列がない場合は、表がまだクエリされていない可能性があります。

ワークロードのクエリパターンが比較的安定している場合は、PREDICATE COLUMNS の使用を選択できます。クエリパターンが可変で、さまざまな列が頻繁に述語として使用される場合、PREDICATE COLUMNS を使用すると一時的に古い統計が返される場合があります。古い統計により、最適でないクエリランタイムプランや長いランタイムにつながる可能性があります。ただし、次に PREDICATE COLUMNS を使用して ANALYZE を実行すると、新しい述語の列が含まれます。

述語の列の詳細を表示するには、次の SQL を使用して PREDICATE\$1COLUMNS という名前のビューを作成します。

```
CREATE VIEW predicate_columns AS
WITH predicate_column_info as (
SELECT ns.nspname AS schema_name, c.relname AS table_name, a.attnum as col_num,  a.attname as col_name,
        CASE
            WHEN 10002 = s.stakind1 THEN array_to_string(stavalues1, '||') 
            WHEN 10002 = s.stakind2 THEN array_to_string(stavalues2, '||')
            WHEN 10002 = s.stakind3 THEN array_to_string(stavalues3, '||')
            WHEN 10002 = s.stakind4 THEN array_to_string(stavalues4, '||')
            ELSE NULL::varchar
        END AS pred_ts
   FROM pg_statistic s
   JOIN pg_class c ON c.oid = s.starelid
   JOIN pg_namespace ns ON c.relnamespace = ns.oid
   JOIN pg_attribute a ON c.oid = a.attrelid AND a.attnum = s.staattnum)
SELECT schema_name, table_name, col_num, col_name,
       pred_ts NOT LIKE '2000-01-01%' AS is_predicate,
       CASE WHEN pred_ts NOT LIKE '2000-01-01%' THEN (split_part(pred_ts, '||',1))::timestamp ELSE NULL::timestamp END as first_predicate_use,
       CASE WHEN pred_ts NOT LIKE '%||2000-01-01%' THEN (split_part(pred_ts, '||',2))::timestamp ELSE NULL::timestamp END as last_analyze
FROM predicate_column_info;
```

LISTING テーブルに対して次のクエリを実行するとします。LISTID、LISTTIME、および EVENTID は、結合、フィルタ、および GROUP BY 句で使用されることに注意してください。

```
select s.buyerid,l.eventid, sum(l.totalprice)
from listing l
join sales s on l.listid = s.listid
where l.listtime > '2008-12-01'
group by l.eventid, s.buyerid;
```

次の例に示すように、PREDICATE\$1COLUMNS ビューをクエリすると、LISTID、EVENTID、および LISTTIME が述語の列としてマークされていることが分かります。

```
select * from predicate_columns 
where table_name = 'listing';
```

```
schema_name | table_name | col_num | col_name       | is_predicate | first_predicate_use | last_analyze       
------------+------------+---------+----------------+--------------+---------------------+--------------------
public      | listing    |       1 | listid         | true         | 2017-05-05 19:27:59 | 2017-05-03 18:27:41
public      | listing    |       2 | sellerid       | false        |                     | 2017-05-03 18:27:41
public      | listing    |       3 | eventid        | true         | 2017-05-16 20:54:32 | 2017-05-03 18:27:41
public      | listing    |       4 | dateid         | false        |                     | 2017-05-03 18:27:41
public      | listing    |       5 | numtickets     | false        |                     | 2017-05-03 18:27:41
public      | listing    |       6 | priceperticket | false        |                     | 2017-05-03 18:27:41
public      | listing    |       7 | totalprice     | false        |                     | 2017-05-03 18:27:41
public      | listing    |       8 | listtime       | true         | 2017-05-16 20:54:32 | 2017-05-03 18:27:41
```

統計を最新状態に保つことで、クエリプランナーが最適なプランを選択できるようになるため、クエリのパフォーマンスが向上します。Amazon Redshift は、統計をバックグラウンドで自動的に更新します。また、明示的に ANALYZE コマンドを実行することもできます。ANALYZE を明示的に実行することを選択した場合は、以下を実行する必要があります。
+ クエリを実行する前に ANALYZE コマンドを実行します。
+ 定期的なロードまたは更新サイクルが終わるたびに、データベースで ANALYZE コマンドを定期的に実行します。
+ 作成した新しいテーブルと大幅に変更された既存のテーブルまたは列で ANALYZE コマンドを実行します。
+ クエリでの使用と変更傾向に基づき、異なるタイプのテーブルおよび列に対し、異なるスケジュールで ANALYZE 操作を実行することを考慮します。
+ 時間とクラスターリソースを節約するには、ANALYZE を実行するときに PREDICATE COLUMNS 句を使用します。

スナップショットをプロビジョニング済みクラスターまたはサーバーレス名前空間に復元した後や、一時停止中のプロビジョニング済みクラスターを再開した後で、ANALYZE コマンドを明示的に実行する必要はありません。Amazon Redshift は、このような場合でもシステムテーブル情報を保持するため、手動の ANALYZE コマンドは不要です。Amazon Redshift は、必要に応じて引き続き自動分析オペレーションを実行します。

分析オペレーションは、最新の統計を含むテーブルを省略します。抽出およびロード (ETL) ワークフローの一環として ANALYZE を実行する場合、自動分析は最新の統計を含むテーブルを省略します。同様に、自動分析によりテーブルの統計が更新された場合、明示的な ANALYZE はテーブルを省略します。

## ANALYZE コマンド履歴
<a name="c_check_last_analyze"></a>

最後の ANALYZE コマンドがテーブルまたはデータベースで実行された日時を知っておくと役立ちます。ANALYZE コマンドが実行されると、Amazon Redshift は以下のような複数のクエリを実行します。

```
padb_fetch_sample: select * from table_name
```

STL\$1ANALYZE をクエリして、分析操作の履歴を表示します。Amazon Redshift が、自動分析でテーブルを分析する場合、`is_background` 列は `t` (true) に設定されます。それ以外の場合は、`f` (false) に設定されます。次の例では、STV\$1TBL\$1PERM を結合して、テーブル名とランタイムの詳細を表示します。

```
select distinct a.xid, trim(t.name) as name, a.status, a.rows, a.modified_rows, a.starttime, a.endtime
from stl_analyze a 
join stv_tbl_perm t  on t.id=a.table_id
where name = 'users'
order by starttime;


xid    | name  | status          | rows  | modified_rows | starttime           | endtime            
-------+-------+-----------------+-------+---------------+---------------------+--------------------
  1582 | users | Full            | 49990 |         49990 | 2016-09-22 22:02:23 | 2016-09-22 22:02:28
244287 | users | Full            | 24992 |         74988 | 2016-10-04 22:50:58 | 2016-10-04 22:51:01
244712 | users | Full            | 49984 |         24992 | 2016-10-04 22:56:07 | 2016-10-04 22:56:07
245071 | users | Skipped         | 49984 |             0 | 2016-10-04 22:58:17 | 2016-10-04 22:58:17
245439 | users | Skipped         | 49984 |          1982 | 2016-10-04 23:00:13 | 2016-10-04 23:00:13
(5 rows)
```

または、ANALYZE コマンドが含まれたすべての完了トランザクションで実行されたすべてのステートメントを返す、より複雑なクエリを実行できます: 

```
select xid, to_char(starttime, 'HH24:MM:SS.MS') as starttime,
datediff(sec,starttime,endtime ) as secs, substring(text, 1, 40)
from svl_statementtext
where sequence = 0
and xid in (select xid from svl_statementtext s where s.text like 'padb_fetch_sample%' )
order by xid desc, starttime;

xid  |  starttime   | secs |                  substring
-----+--------------+------+------------------------------------------
1338 | 12:04:28.511 |    4 | Analyze date
1338 | 12:04:28.511 |    1 | padb_fetch_sample: select count(*) from
1338 | 12:04:29.443 |    2 | padb_fetch_sample: select * from date
1338 | 12:04:31.456 |    1 | padb_fetch_sample: select * from date
1337 | 12:04:24.388 |    1 | padb_fetch_sample: select count(*) from
1337 | 12:04:24.388 |    4 | Analyze sales
1337 | 12:04:25.322 |    2 | padb_fetch_sample: select * from sales
1337 | 12:04:27.363 |    1 | padb_fetch_sample: select * from sales
...
```

# テーブルのバキューム処理
<a name="t_Reclaiming_storage_space202"></a>

Amazon Redshift は、バックグラウンドでテーブルを自動でソートし、VACUUM DELETE オペレーションを実行できます。ロードまたは一連の増分更新の後にテーブルをクリーンアップするには、データベース全体または個々のテーブルに対して [VACUUM](r_VACUUM_command.md) コマンドを実行することもできます。

**注記**  
必要なテーブルのアクセス許可を持つユーザーのみが、テーブルのバキューム処理を効果的に行うことができます。必要なテーブルアクセス許可なしで VACUUM が実行された場合、オペレーションは完了しますが、効果はありません。バキューム処理を効果的に実行するための有効なテーブルのアクセス許可のリストについては、「[VACUUM](r_VACUUM_command.md)」を参照してください。  
このため、必要に応じて、テーブルを個別にバキューム処理することをお勧めします。この方法をお勧めするもう 1 つの理由は、データベース全体をバキューム処理すると、コストのかかるオペレーションになる場合があるからです。

## 自動テーブルソート
<a name="automatic-table-sort"></a>

Amazon Redshift は、データをバックグラウンドで自動的にソートし、テーブルデータをソートキー順に維持します。Amazon Redshift は、スキャンクエリを追跡し、テーブルのどのセクションがソートする利点あるかを判断します。Amazon Redshift は、同時実行スケーリングクラスターからのスキャンクエリも追跡します。Amazon Redshift データ共有を使用するマルチクラスターアーキテクチャの場合、Amazon Redshift は、異なるリージョンのクラスター/ワークグループを含む、データメッシュ内のコンシューマークラスター/ワークグループから発生するスキャンクエリも追跡します。メインクラスター、同時実行スケーリングクラスター、コンシューマークラスターからのスキャン統計が集約され、テーブルのどのセクションがソートの恩恵を受けるかが決まります。

システムの負荷に応じて、Amazon Redshift は自動でソートを開始します。この自動ソートにより、データをソートキー順に維持するために VACUUM コマンドを実行する必要が少なくなります。例えば、大きなデータをロードした後に、ソートキー順でデータを完全にソートする必要がある場合でも、VACUUM コマンドを手動で実行することができます。VACUUM SORT コマンドの実行が有効的かどうかを判断するには、`vacuum_sort_benefit`の[SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)をモニタします。

Amazon Redshift は、各テーブルのソートキーを使用するスキャンクエリを追跡します。Amazon Redshift は、テーブルが完全にソートされている場合、各テーブルのデータのスキャンやフィルターの最大改善率を見積ります。この見積もりは、`vacuum_sort_benefit`の[SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md)列で表示されます。この列は、`unsorted`列と一緒に使用することができ、クエリの際、いつテーブルで VACUUM SORT を手動で実行したら効率的かを判断します。`unsorted`列は、テーブルの物理的なソート順を反映しています。`vacuum_sort_benefit` 列は、VACUUM SORT を手動で実行することでソートによるテーブルへの影響を特定します。

例えば、次のクエリを考えてみます。

```
select "table", unsorted,vacuum_sort_benefit from svv_table_info order by 1;
```

```
 table | unsorted | vacuum_sort_benefit 
-------+----------+---------------------
 sales |    85.71 |                5.00
 event |    45.24 |               67.00
```

「sales」というテーブルの場合、86% が物理的にソートされていなくても、86% ソートされていないテーブルからのクエリ実行の影響は、5% だけとなります。理由としては、クエリがテーブルの一部にしかアクセスしていないか、ごく少数のクエリがテーブルにアクセスしたかのどちらかとなります。「event」というテーブルの場合、テーブルは、45% が物理的にソートされていません。ですが、67% のクエリ実行の影響は、クエリがテーブルの大部分にアクセスしたか、テーブルにアクセスしたクエリが多かったことを表しています。「event」というテーブルには、VACUUM SORT の実行が潜在的に有効となります。

## 自動バキューム削除
<a name="automatic-table-delete"></a>

削除を実行すると、行は削除対象としてマークされますが、削除されません。Amazon Redshift は、データベーステーブルの削除された行数に基づいて、バックグラウンドで VACUUM DELETE オペレーションを自動的に実行します。Amazon Redshift では、負荷が軽減されているときに VACUUM DELETE を実行するようにスケジュールし、負荷が高いときにはオペレーションを一時停止します。

**Topics**
+ [自動テーブルソート](#automatic-table-sort)
+ [自動バキューム削除](#automatic-table-delete)
+ [VACUUM の頻度](#vacuum-frequency)
+ [ソートステージとマージステージ](#vacuum-stages)
+ [バキュームのしきい値](#vacuum-sort-threshold)
+ [バキュームの種類](#vacuum-types)
+ [バキューム処理時間の最小化](vacuum-managing-vacuum-times.md)

## VACUUM の頻度
<a name="vacuum-frequency"></a>

一貫性のあるクエリパフォーマンスを維持するために、必要な頻度でバキューム処理を実行する必要があります。VACUUM コマンドの実行頻度を決めるときは、これらの要因を考慮します。
+ VACUUM は、夜間や指定されたデータベース管理期間など、クラスターのアクティビティが最小限になると予想される期間に実行します。
+ メンテナンスウィンドウ以外で VACUUM コマンドを実行します。詳細については、「[保守時間の時間枠を回避したスケジュール計画](https://docs.aws.amazon.com/redshift/latest/dg/c_best-practices-avoid-maintenance.html)」を参照してください。
+ 大きなリージョンが未ソートの状態であれば、バキューム処理の時間が長くなります。バキューム処理を遅らせる場合、再整理しなければならないデータが増えるのでバキューム処理にかかる時間が長くなります。
+ VACUUM は I/O 集約型な操作です。そのため、バキューム処理の完了にかかる時間が長ければ、同時クエリとクラスターで実行されている他のデータベース操作に与える影響が大きくなります。
+ VACUUM は、インターリーブソートを使用するテーブルに対しては時間がかかります。インターリーブテーブルを再ソートする必要があるかどうかを評価するには、[SVV\$1INTERLEAVED\$1COLUMNS](r_SVV_INTERLEAVED_COLUMNS.md) ビューのクエリを実行します。

## ソートステージとマージステージ
<a name="vacuum-stages"></a>

Amazon Redshift では、2 つのステージでバキュームオペレーションを実行します。最初に未ソートのリージョン内の行をソートし、続いて必要に応じて、テーブルの最後の新しくソートされた行に既存の行をマージします。大きなテーブルでバキュームを実行すると、バキューム操作は一連の差分ソートから成るステップを実行した後で、マージを実行します。オペレーションが失敗した場合、または Amazon Redshift がバキュームの間にオフラインになった場合は、部分的にバキュームが実行されたテーブルまたはデータベースは一貫性のある状態が保たれますが、バキュームオペレーションを手動で再開する必要があります。差分ソートは失われますが、操作が失敗する前にコミットされたマージ済みの行に再度バキューム処理を実行する必要はありません。未ソートのリージョンが大きい場合は、無駄になる時間が大きくなる可能性があります。ソートとマージのステージの詳細については、「[マージ済みの行のボリューム管理](vacuum-managing-vacuum-times.md#vacuum-managing-volume-of-unmerged-rows)」を参照してください。

ユーザーは、バキューム処理中のテーブルにアクセスできます。バキューム処理中のテーブルにクエリおよび書き込み操作を実行できますが、DML およびバキュームを同時に実行すると両方の処理時間が長くなる可能性があります。バキューム処理中に UPDATE および DELETE ステートメントを実行する場合は、システムのパフォーマンスが低減する場合があります。差分マージにより UPDATE と DELETE の同時操作が一時的にブロックされ、UPDATE と DELETE により操作で影響のあるテーブルでのマージのステップが一時的にブロックされます。ALTER TABLE などの DDL 操作は、テーブルでバキューム操作が終了するまでブロックされます。

**注記**  
VACUUM の様々な修飾子により、その動作方法が制御されます。それらを使用して、現在のニーズに合わせてバキュームオペレーションを調整することができます。例えば、VACUUM RECLUSTER を使用すると、完全なマージ操作が実行されないので、バキューム操作が短縮されます。詳細については、「[VACUUM](r_VACUUM_command.md)」を参照してください。

## バキュームのしきい値
<a name="vacuum-sort-threshold"></a>

デフォルトではVACUUM コマンドで、テーブルの行の 95 パーセント以上がすでにソートされているテーブルのソートフェーズをスキップします。ソートフェーズをスキップすることにより、VACUUM のパフォーマンスが大幅に向上します。VACUUM コマンドを実行するとき、テーブル名および TO *threshold* PERCENT パラメータを含む 1 つのテーブルの、デフォルトのソートしきい値を変更する。

## バキュームの種類
<a name="vacuum-types"></a>

バキュームのタイプ別の詳細については、「[VACUUM](r_VACUUM_command.md)」を参照してください。

# バキューム処理時間の最小化
<a name="vacuum-managing-vacuum-times"></a>

 Amazon Redshift は、背景で自動的にデータをソートし、VACUUM DELETE を実行します。これにより、VACUUM コマンドを実行する必要が少なくなります。バキューム処理は時間がかかる可能性があります。データの特性に応じて、バキューム処理時間を最小化するために、以下のプラクティスをお勧めします。

**Topics**
+ [インデックスを再生成するかどうかの決定](#r_vacuum-decide-whether-to-reindex)
+ [未ソートリージョンのサイズを管理する](#r_vacuum_diskspacereqs)
+ [マージ済みの行のボリューム管理](#vacuum-managing-volume-of-unmerged-rows)
+ [ソートキー順序でデータをロードする](#vacuum-load-in-sort-key-order)
+ [時系列テーブルを使用して保存データを削減する](#vacuum-time-series-tables)

## インデックスを再生成するかどうかの決定
<a name="r_vacuum-decide-whether-to-reindex"></a>

多くの場合、インターリーブソート方式を使用することで、クエリのパフォーマンスを大幅に向上させることができますが、時間の経過とともに、ソートキー列の値の分散が変わった場合、パフォーマンス低下につながることがあります。

最初に COPY または CREATE TABLE AS を使用して空のインターリーブテーブルをロードすると、Amazon Redshift は自動的にインターリーブインデックスを構築します。最初に INSERT を使用してインターリーブテーブルをロードする場合は、その後に VACUUM REINDEX を実行して、インターリーブインデックスを初期化する必要があります。

時間の経過と共に、新しいソートキー値を持つ行を追加するにつれて、ソートキー列の値の分布が変更されると、パフォーマンスが低下する可能性があります。新しい行が既存のソートキー値の範囲内に主に存在する場合、インデックスを再作成する必要はありません。VACUUM SORT ONLY あるいは VACUUM FULL を実行して、ソート順序を復元します。

クエリエンジンはソート順を使用して、クエリの処理用にスキャンする必要のあるデータブロックを効率的に選択できます。インターリーブソートの場合、Amazon Redshift はソートキー列の値を分析して、最適なソート順を決定します。行が追加されて、キー値の分散が変わった、つまりスキューが発生した場合、ソート方法は最適でなくなり、ソートのパフォーマンス低下につながります。ソートキーの分散を再分析するには、VACUUM REINDEX を実行できます。REINDEX オペレーションには時間がかかるため、テーブルに対してインデックスの再生成が有効かどうかを決定するには、[SVV\$1INTERLEAVED\$1COLUMNS](r_SVV_INTERLEAVED_COLUMNS.md) ビューのクエリを実行します。

例えば、以下のクエリを実行すると、インターリーブソートキーを使用するテーブルについて詳細が表示されます。

```
select tbl as tbl_id, stv_tbl_perm.name as table_name, 
col, interleaved_skew, last_reindex
from svv_interleaved_columns, stv_tbl_perm
where svv_interleaved_columns.tbl = stv_tbl_perm.id
and interleaved_skew is not null;


 tbl_id | table_name | col | interleaved_skew | last_reindex
--------+------------+-----+------------------+--------------------
 100048 | customer   |   0 |             3.65 | 2015-04-22 22:05:45
 100068 | lineorder  |   1 |             2.65 | 2015-04-22 22:05:45
 100072 | part       |   0 |             1.65 | 2015-04-22 22:05:45
 100077 | supplier   |   1 |             1.00 | 2015-04-22 22:05:45
(4 rows)
```

`interleaved_skew` の値はスキューの量を示す比率です。値が 1 の場合、スキューがないことを意味します。スキューが 1.4 よりも大きい場合、基とするセットからのスキューでなければ、VACUUM REINDEX により通常はパフォーマンスが向上します。

`last_reindex` で日付値を使用して、前回のインデックス再生成から経過した時間を調べることができます。

## 未ソートリージョンのサイズを管理する
<a name="r_vacuum_diskspacereqs"></a>

データがすでに含まれているテーブルに大量の新しいデータをロードするか、定期的な保守管理操作の一環としてテーブルのバキューム処理を実行しないとき、未ソートのリージョンが増えます。長時間のバキューム操作を避けるために、以下の手法を利用できます。
+ 定期的なスケジュールでバキューム操作を実行します。

  (テーブルの合計行数の少ないパーセンテージを表す毎日の更新など) 少ない増分でテーブルをロードする場合、VACUUM を定期的に実行すると、個別のバキューム操作が短時間で終了します。
+ 最も大きなロードを最初に実行します。

  複数の COPY 操作で新しいテーブルをロードする必要がある場合、最も大きなロードを最初に実行します。新しいテーブルまたはTRUNCATE されたテーブルに初回ロードを実行すると、すべてのデータがソート済みリージョンに直接ロードされます。そのため、バキュームは必要ありません。
+ すべての行を削除するのではなく、テーブルの全データを削除します (Truncate)。

  テーブルから行を削除した場合、その行が占有していた領域はバキューム操作を実行するまで再利用されません。ただし、テーブルの全データを削除した（Truncate）場合、テーブルが空になり、ディスク領域が再利用されます。そのため、バキュームは必要ありません。または、テーブルを削除し (Drop)、再作成します。
+ テストテーブルの全データを削除するか、テーブル自体を削除します。

  テスト目的で少ない数の行をテーブルにロードする場合、完了時に行を削除しないでください。代わりに、テーブルの全データを削除し、後続の本稼働のロード操作の一環としてこれらの行を再ロードします。
+ ディープコピーを実行します。

  複合ソートキーテーブルを使用するテーブルにソートされていない大きなリージョンがある場合、ディープコピーがバキュームよりずっと高速です。ディープコピーでは、一括挿入を使用してテーブルが再作成され、再設定されます。これにより、テーブルが自動的に再ソートされます。テーブルにソートされていない大規模なリージョンがある場合、ディープコピーの方がバキューム処理より高速です。欠点としては、ディープコピー処理中は同時更新を実行できません。バキューム処理では実行できます。詳細については、「[Amazon Redshift クエリの設計のベストプラクティス](c_designing-queries-best-practices.md)」を参照してください。

## マージ済みの行のボリューム管理
<a name="vacuum-managing-volume-of-unmerged-rows"></a>

バキューム操作で新しい行をテーブルのソート済みリージョンにマージする必要がある場合、バキュームに必要な時間はテーブルが大きくなるにつれて長くなります。マージが必要な行の数を少なくすると、バキュームのパフォーマンスが向上します。

バキューム処理前のテーブルは、最初にソート済みリージョン、その後ろに未ソートのリージョンで構成され、未ソート領域は行の追加または更新が行われると大きくなります。COPY 操作で行のセットが追加された場合、新しい行のセットは、テーブルの最後の未ソート領域に追加されたときにソートキーでソートされます。新しい行は、未ソートリージョン内ではなく固有のセット内で順序付けされます。

次の図は、2 つの連続する COPY 操作後の未ソートのリージョンを示しています。ソートキーは CUSTID です。分かりやすいように、この例では複合ソートキーを示していますが、インターリーブテーブルにより未ソートリージョンの影響が大きくならなければ、同じ原則はインターリーブソートキーにも当てはまります。

![\[2 つの COPY オペレーションからのレコードを保持するソートされていないテーブル。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-unsorted-region.png)


バキュームにより、2 つのステージでテーブルのソート順が元に戻ります。

1. 未ソートのリージョンを新しくソートされたリージョンにソートします。

   最初のステージでは未ソートのリージョンのみが書き換えられるため、比較的低コストです。新しくソートされたリージョンのソートキーの値の範囲が既存の範囲を超えた場合、新しい行のみを書き換える必要があり、バキュームは完了します。例えば、ソート済みリージョンに 1～500 の ID 値が含まれ、それ以降のコピーオペレーションで追加されたキーの値が 500 を超えた場合は、未ソートのリージョンのみを書き換える必要があります。

1. 新しくソートされたリージョンと前にソートされたリージョンをマージします。

   新しくソートされたリージョンのキーとソート済みリージョンのキーが重複する場合は、VACUUM で行をマージする必要があります。新しくソートされたリージョンの先頭から開始すると (最も低いソートキーで)、バキュームにより、前にソートされたリージョンおよび新しくソートされたリージョンからマージされた行が新しいブロックのセットに書き込まれます。

新しいソートキーの範囲と既存のソートキーが重複する範囲により、再度書き込む必要のあるソート済みリージョンの範囲が決まります。未ソートのキーが既存のソート範囲全体に分散する場合は、バキュームにより、テーブルの既存部分を再度書き込む必要があります。

次の図は、テーブルに追加された行をバキュームによってソートおよびマージする方法を示しています。CUSTID はソートキーです。各コピー操作により、既存のキーと重複するキー値を持つ新しい行セットが追加されるため、テーブルのほぼ全体を再度書き込む必要があります。図に示されているのは単一のソートとマージですが、実際には、大規模なバキュームは一連の差分ソートおよびマージステップから成ります。

![\[サンプルテーブルの VACUUM オペレーションを 2 つのステップで実行します。最初に新しい行がソートされ、既存の行とマージされます。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-unsorted-region-sort-merge.png)


新しい行のセットのソートキーの範囲が既存のキーの範囲と重複する場合、マージステージのコストは、テーブルが大きくなると、テーブルサイズに比例して大きくなります。一方、ソートステージのコストは、未ソートリージョンのサイズに比例したままとなります。このような場合、次の図に示すように、マージステージのコストはソートステージのコストを上回ります。

![\[新しい行に既存の行と重複するソートキーがある場合に、マージステージがどのように高価になるかを示す図。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-example-merge-region-grows.png)


テーブルのどれだけの部分が再マージされたかを特定するには、バキューム操作が完了した後で SVV\$1VACUUM\$1SUMMARY のクエリを行います。次のクエリは、CUSTSALES が時間の経過と共に大きくなったときに、6 回連続でバキュームを実行した場合の効果を示します。

```
select * from svv_vacuum_summary
where table_name = 'custsales';


 table_name | xid  | sort_      | merge_     | elapsed_   | row_  | sortedrow_ | block_  | max_merge_
            |      | partitions | increments | time       | delta | delta      | delta   | partitions
 -----------+------+------------+------------+------------+-------+------------+---------+---------------
  custsales | 7072 |          3 |          2 |  143918314 |     0 |   88297472 |   1524  |      47
  custsales | 7122 |          3 |          3 |  164157882 |     0 |   88297472 |    772  |      47
  custsales | 7212 |          3 |          4 |  187433171 |     0 |   88297472 |    767  |      47
  custsales | 7289 |          3 |          4 |  255482945 |     0 |   88297472 |    770  |      47
  custsales | 7420 |          3 |          5 |  316583833 |     0 |   88297472 |    769  |      47
  custsales | 9007 |          3 |          6 |  306685472 |     0 |   88297472 |    772  |      47
 (6 rows)
```

merge\$1increments 列は、バキューム操作ごとにマージされたデータの量を示します。連続バキュームを超えるマージインクリメントの数がテーブルサイズの増加と比例して増えた場合は、既存のソート済みリージョンと新たにソートされるリージョンが重複するため、バキューム操作ごとにテーブル内の行数が増加して再マージされていることを示します。

## ソートキー順序でデータをロードする
<a name="vacuum-load-in-sort-key-order"></a>

COPY コマンドを使用してソートキー順序でデータをロードする場合、バキューム処理の必要性が減少するか、なくなることもあります。

COPY では、以下のすべてが該当する場合に、テーブルのソート済みリージョンに自動的に新しい行が追加されます。
+ テーブルでは、1 つのソート列のみで複合ソートキーが使用されます。
+ ソート列は NOT NULL です。
+ テーブルは 100% ソート済みであるか空です。
+ すべての新しい行は、既存の行 (削除対象としてマークされた行も含む) よりソート順が高くなっています。この場合、Amazon Redshift では、ソートキーの最初の 8 バイトを使用してソート順が決定されます。
+  COPY コマンドは、特定の負荷最適化をトリガーしません。大量のデータをロードする場合、Amazon Redshift はテーブルのソートされたリージョンに行を追加するのではなく、新しいソートされたパーティションを作成することでパフォーマンスを最適化できます。

例えば、顧客 ID と時刻を使用して顧客イベントを記録するテーブルがあるとします。顧客 ID でソートする場合は、前の例に示すとおり、差分ロードによって新たに追加された行のソートキー範囲が既存の範囲と重複し、コストの高いバキューム操作につながる可能性があります。

タイムスタンプ列にソートキーを設定する場合、新しい行は、次の図に示すとおり、テーブルの末尾にソート順で追加されるため、バキュームの必要が減少するか、なくなります。

![\[タイムスタンプ列をソートキーとして使用し、ソートが不要な新しいレコードを取得するテーブル。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-unsorted-region-date-sort.png)


## 時系列テーブルを使用して保存データを削減する
<a name="vacuum-time-series-tables"></a>

ローリング期間のデータを保持する場合は、次の図に示すとおり、一連のテーブルを使用します。

![\[5 つの四半期データを含む 5 つのテーブル。最も古いテーブルは、1 年分の推移を維持するために削除されます。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/vacuum-example-unsorted-region-copy-time-series.png)


データセットを追加するたびに新しいテーブルを作成して、シリーズの最も古いテーブルを削除します。次のような二重の利点があります。
+ DROP TABLE 操作は大量の DELETE よりもはるかに効率的であるため、行を削除する余分なコストを避けることができます。
+ テーブルがタイムスタンプでソートされる場合は、バキュームは必要ではありません。各テーブルに 1 か月のデータが含まれる場合、テーブルがタイムスタンプでソートされていない場合でも、バキュームで最大でも 1 か月分のデータを再書き込みする必要があります。

レポーティングクエリで使用するために、UNION ALL ビューを作成し、データが複数のテーブルに保存されているという事実を隠すことができます。クエリがソートキーでフィルタリングされる場合は、クエリプランナーは使用されないすべてのテーブルを効率的にスキップできます。その他の種類のクエリでは UNION ALL の効率が下がる可能性があるため、テーブルを使用するすべてのクエリのコンテキストでクエリパフォーマンスを評価してください。

# 同時書き込み操作を管理する
<a name="c_Concurrent_writes"></a>

一部のアプリケーションでは、クエリとロードを同時に行うだけでなく、複数のテーブルまたは同じテーブルに同時に書き込む能力を必要とします。この文脈では、*同時*とは、厳密に同じ時間に実行するようにスケジュールするという意味ではなく、重複するという意味です。最初のトランザクションがコミットする前に 2 つ目のトランザクションが開始する場合、2 つのトランザクションは同時であると考えられます。同時操作は、同じユーザーまたは異なるユーザーが制御する異なるセッションから発生する可能性があります。

Amazon Redshift では増分ロードまたは増分変更の実行中にテーブル読み込みができるので、これらのアプリケーションがサポートされます。クエリは、コミットする次のバージョンの待機ではなく、データの最新コミットバージョンまたは*スナップショット*だけを確認します。特定のクエリに別の書き込み操作からのコミットを待機させる場合、それを適宜スケジュールする必要があります。

**注記**  
Amazon Redshift はデフォルトで*自動コミット*動作がサポートされています。この機能では、個別に実行された SQL コマンドが個別にコミットします。([BEGIN](r_BEGIN.md) および [END](r_END.md) ステートメントにより定義された) トランザクションブロックに一連のコマンドを含めた場合、そのブロックは 1 つのトランザクションとしてコミットされます。そのため、必要に応じてロールバックできます。この動作の例外は、TRUNCATE コマンドと VACUUM コマンドです。このコマンドは、現在のトランザクションで行われた未処理の変更をすべて自動的にコミットします。  
一部の SQL クライアントでは、BEGIN コマンドと COMMIT コマンドが自動的に発行されるため、クライアントは、ステートメントのグループをトランザクションとして実行するか、個々のステートメントを独自のトランザクションとして実行するかを制御します。使用しているインターフェイスのマニュアルを確認してください。例えば、Amazon Redshift JDBC ドライバーを使用している場合、複数の (セミコロンで区切られた) SQL コマンドを含むクエリ文字列を持つ JDBC `PreparedStatement` は、すべてのステートメントを 1 つのトランザクションとして実行します。対照的に、SQL Workbench/J を使用して AUTO COMMIT ON を設定した後、複数のステートメントを実行すると、各文が独自のトランザクションとして実行されます。

次のトピックでは、トランザクション、データベーススナップショット、更新、同時動作など、主要な概念とユースケースの一部を紹介します。

**Topics**
+ [Amazon Redshift の分離レベル](c_serial_isolation.md)
+ [書き込みおよび読み取り/書き込みオペレーション](c_write_readwrite.md)
+ [同時書き込みの例](r_Serializable_isolation_example.md)
+ [直列化可能な分離エラーのトラブルシューティング](c_serial_isolation-serializable-isolation-troubleshooting.md)

# Amazon Redshift の分離レベル
<a name="c_serial_isolation"></a>

Amazon Redshift では、同時書き込みオペレーションはテーブルの書き込みロックと*直列化分離*を利用して安全にサポートされます。直列化分離では、テーブルに対して実行されるトランザクションは、そのテーブルに対して実行される唯一のトランザクションであるという錯覚が守られます。

Amazon Redshift データベースは、トランザクションの開始時に各オペレーションでデータの最新のコミット済みバージョンまたはスナップショットを使用することにより、同時書き込み操作をサポートします。データベーススナップショットは、ほとんどの SELECT ステートメント、COPY、DELETE、INSERT、UPDATE、TRUNCATE などの DML コマンド、次の DDL コマンドの最初の発生時にトランザクション内で作成されます。
+  ALTER TABLE (列を追加または削除する) 
+  CREATE TABLE 
+  DROP TABLE 
+  TRUNCATE TABLE 

他のトランザクションはこのスナップショットを変更できません。つまり、トランザクションは互いに分離されます。同時トランザクションは互いに認識されません。互いの変更を検出できません。

どのトランザクションの同時実行も、それらのトランザクションの直列実行と同じ結果を生成する必要があります。そのようなトランザクションの直列実行で、同じ結果が生成されない場合、直列化可能性を阻害する可能性のあるステートメントを実行するトランザクションが中断され、ロールバックされます。

例えば、ユーザーが T1 と T2 の 2 つの同時トランザクションを実行しようとするとします。T1 と T2 を実行すると、次のシナリオの少なくとも 1 つと同じ結果が生成されます。
+ T1 と T2 がこの順序で連続して実行されます。
+ T2 と T1 がこの順序で連続して実行されます。

 Amazon Redshift の分離レベルは、次の問題を防ぎます。
+  ダーティ読み取り - ダーティ読み取りは、トランザクションがコミットされていないデータを読み取ったときに発生します。例えば、トランザクション 1 が行を更新するとします。トランザクション 2 は T1 が更新をコミットする前に、更新された行を読み取ります。T1 が変更をロールバックすると、T2 は Amazon Redshift が存在したことがないと見なすコミットされていない行のデータを読み取ります。
+  再現不可能な読み取り - 再現不可能な読み取りは、1 つのトランザクションが同じ行を 2 回読み取るが、毎回異なるデータを取得する場合に発生します。例えば、トランザクション 1 が行を読み取るとします。トランザクション 2 は、その行を更新または削除し、更新または削除をコミットします。T1 が行を再読み込みすると、異なる行値を取得するか、行が削除されたことを検出します。
+  ファントム – ファントムは、検索条件に一致するが、最初は表示されない行です。例えば、トランザクション 1 が、その検索条件を満たす行のセットを読み取るとします。トランザクション 2 は、T1 の検索条件に一致する UPDATE ステートメントまたは INSERT ステートメントに新しい行を生成します。T1 が検索ステートメントを再実行すると、別の行セットを取得します。

## SNAPSHOT と SERIALIZABLE の分離
<a name="c_serial_isolation-snapshot_and_serializable"></a>

SERIALIZABLE と SNAPSHOT は、Amazon Redshift で利用できる、直列化可能な分離レベルです。

SNAPSHOT 分離は、プロビジョニングされたクラスターとサーバーレスワークグループを作成するときのデフォルトの分離レベルであり、SERIALIZABLE 分離よりも大量のデータを短時間で処理できます。

SERIALIZABLE の分離には時間がかかりますが、同時トランザクションにはより厳しい制約を実装します。この分離レベルは、1 つのトランザクションのみをコミットし、直列化可能な分離違反エラーで他のすべての同時トランザクションをキャンセルすることで、書き込みスキューの異常などの問題を防ぎます。

以下は、SNAPSHOT 分離を使用する場合に 2 つの同時書き込み操作を処理する方法のタイムラインの例です。各ユーザーの UPDATE ステートメントは、同じ行を更新しようとする競合がないため、コミットが許可されます。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_serial_isolation.html)

直列化可能な分離を使用して同じシナリオを実行する場合、Amazon Redshift は直列化可能な分離違反によりユーザー 2 を終了し、エラー `1023` を返します。詳細については、「[直列化可能な分離エラーのトラブルシューティング](c_serial_isolation-serializable-isolation-troubleshooting.md)」を参照してください。この場合、ユーザー 1 だけが正常にコミットできます。

## 考慮事項
<a name="c_serial_isolation-considerations"></a>

Amazon Redshift の分離レベルを使用する場合、以下の点を考慮してください。
+  STV\$1DB\$1ISOLATION\$1LEVEL カタログビューをクエリして、データベースが使用している分離レベルを表示します。詳細については、「[STV\$1DB\$1ISOLATION\$1LEVEL](r_STV_DB_ISOLATION_LEVEL.md)」を参照してください。
+  PG\$1DATABASE\$1INFO ビューをクエリして、データベースでサポートされている同時トランザクションの数を確認します。詳細については、「[PG\$1DATABASE\$1INFO](r_PG_DATABASE_INFO.md)」を参照してください。
+  システムカタログテーブル (PG) と他の Amazon Redshift システムテーブルはトランザクション内にロックされません。そのため、DDL および TRUNCATE オペレーションから発生したデータベースオブジェクトに対する変更は、いずれかの同時トランザクションにコミットすることで表示が可能になります。

   例えば、T1 と T2 という 2 つの同時トランザクションが開始するとき、テーブル A がデータベースに存在します。今、T2 が、テーブルのリストを PG\$1TABLES カタログテーブルから選択して返しているとします。この時、T1 はテーブル A をドロップしてコミットし、その後 T2 はテーブルを再度リストします。この後、テーブル A はリストされることはなくなります。T2 が削除されたテーブルのクエリを試行すると、Amazon Redshift は "関係が存在しない" というエラーを返します。T2 にテーブルのリストを返す、またはテーブル A が存在することをチェックするカタログクエリは、ユーザーテーブルに対し実行されるオペレーションと同じ分離ルールの対象にはなりません。

   これらのテーブルに対する更新のトランザクションはコミット済み読み取り分離モードで実行されます。
+  PG プレフィックスのカタログテーブルは、スナップショットの分離をサポートしていません。

# 書き込みおよび読み取り/書き込みオペレーション
<a name="c_write_readwrite"></a>

異なるタイプのコマンドを実行するタイミングと方法を決定することで、同時書き込み操作の特定の動作を管理できます。次のコマンドがこの話題に関連します。
+ COPY コマンド、(初回または増分) ロードを実行します
+ INSERT コマンド、1 つまたは複数の行を 1 回で追加します
+ UPDATE コマンド、既存の行を変更します
+ DELETE コマンド、行を削除します 

COPY および INSERT オペレーションは純粋な書き込みオペレーションです。DELETE オペレーションと UPDATE オペレーションは読み取り/書き込みオペレーションです (行を削除または更新するには、最初に読み取る必要があります)。同時書き込み操作の結果は、同時に実行されている特定のコマンドに依存します。

UPDATE 操作と DELETE 操作は、書き込み前に初回テーブル読み込みに依存するため、動作が異なります。同時トランザクションが互いに表示されるとすれば、UPDATE と DELETE は最後のコミットからデータのスナップショットを読み取る必要があります。最初の UPDATE または DELETE がそのロックを解除するとき、2 つ目の UPDATE または DELETE はそれがこれから処理するデータが古くなっている可能性がないか決定する必要があります。最初のトランザクションでそのロックが解除されるまで 2 つ目のトランザクションでデータのスナップショットが取得されないため、データは古くなりません。

## 複数のテーブルが関連する同時書き込みトランザクションで発生する可能性のあるデッドロック状況
<a name="c_write_readwrite-potential-deadlock"></a>

トランザクションに複数のテーブルの更新が関連するとき、両方が同じテーブルセットに書き込もうとすると、同時実行トランザクションにデッドロックが発生する可能性があります。コミットまたはロールバックするとき、トランザクションはそのすべてのテーブルロックを一度に解除します。1 つずつロックを解除することはありません。

例えば、T1 と T2 というトランザクションが大体同じ時間に開始します。T1 がテーブル A に書き込みを開始し、T2 がテーブル B に書き込みを開始する場合、両方のトランザクションは競合なく進行します。ただし、T1 がテーブル A への書き込みを終了し、テーブル B への書き込みを開始する必要がある場合、T2 が引き続き B をロックしているため、T1 は進行できません。同様に、T2 がテーブル B への書き込みを終了し、テーブル A への書き込みを開始する必要がある場合、T1 が引き続き A をロックしているため、T2 は進行できません。その書き込みオペレーションがコミットされるまでいずれのトランザクションもそのロックを解除できないため、いずれのトランザクションも進行できません。この種のデッドロックを回避するには、同時書き込みオペレーションの日程を注意深く計画する必要があります。例えば、常にトランザクションと同じ順序でテーブルを更新する必要があります。ロックを指定する場合、DML 操作を実行する前に同じ順序でテーブルをロックします。

## 単一のテーブルが関連する同時書き込みトランザクションの考えられるデッドロック状況
<a name="c_write_readwrite-potential-deadlock-single"></a>

スナップショット分離環境では、同じテーブルで同時に書き込みトランザクションを実行するとデッドロックが発生する可能性があります。スナップショット分離デッドロックは、INSERT ステートメントまたは COPY ステートメントがロックを共有して同時に進行しており、別のステートメントが同じテーブルで排他的ロックを必要とするオペレーション (UPDATE、DELETE、MERGE、DDL) を実行する必要がある場合に発生します。

次のシナリオを考えてみます。

トランザクション 1 (T1):

```
INSERT/COPY INTO table_A;
```

トランザクション 2 (T2):

```
INSERT/COPY INTO table_A; 
            <UPDATE/DELETE/MERGE/DDL statement> table_A
```

デッドロックは、INSERT オペレーションまたは COPY オペレーションを行う複数のトランザクションが共有ロックを使用して同じテーブルで同時に実行され、それらのトランザクションの 1 つが、純粋な書き込みオペレーションの後に排他的ロックを必要とするオペレーション (UPDATE、MERGE、DELETE、または DDL ステートメントなど) を続けて実行しようとする場合に発生する可能性があります。

このような状況でデッドロックを回避するには、排他的ロックを必要とするステートメント (UPDATE/MERGE/DELETE/DDL ステートメント) を別のトランザクションに分割して、INSERT/COPY ステートメントを同時に進行させ、その後排他的ロックを必要とするステートメントを実行するようにします。または、同じテーブルで INSERT/COPY ステートメントと MERGE/UPDATE/MERGE ステートメントを使用するトランザクションの場合、アプリケーションに再試行ロジックを含めて、潜在的なデッドロックを回避できます。

# 同時書き込みの例
<a name="r_Serializable_isolation_example"></a>

次の疑似コードの例は、同時に実行されたときに、トランザクションが進行または待機する仕組みを示しています。

## 直列化可能な分離を使用した同時書き込みの例
<a name="r_Serializable_isolation_example-serializable"></a>

### 直列化可能な分離を使用した同じテーブルへの同時 COPY オペレーション
<a name="r_Serializable_isolation_example-concurrent-copy-operations-into-the-same-table"></a>

トランザクション 1 は LISTING テーブルに行をコピーします: 

```
begin;
copy listing from ...;
end;
```

トランザクション 2 は別のセッションで同時に開始され、さらに多くの行を LISTING テーブルにコピーしようとします。トランザクション 2 は、トランザクション 1 が LISTING テーブルの書き込みロックを解除するまで待機する必要があります。その後、続行できます。

```
begin;
[waits]
copy listing from ;
end;
```

片方または両方のトランザクションに COPY コマンドの代わりに INSERT コマンドが含まれる場合、同じ動作が起こることがあります。

### 直列化可能な分離を使用した同じテーブルからの同時 DELETE オペレーション
<a name="r_Serializable_isolation_example-concurrent-delete-operations-from-the-same-table"></a>

トランザクション 1 がテーブルから行を削除します: 

```
begin;
delete from listing where ...;
end;
```

トランザクション 2 が同時に開始され、同じテーブルから行を削除しようとします。行の削除を試行する前にトランザクション 1 の完了を待つため、トランザクション 2 は成功します。

```
begin
[waits]
delete from listing where ;
end;
```

片方または両方のトランザクションに DELETE コマンドの代わりに同じテーブルへの UPDATE コマンドが含まれる場合、同じ動作が起こることがあります。

### 直列化可能な分離を使用した読み取りオペレーションと書き込みオペレーションがミックスされた同時トランザクション
<a name="r_Serializable_isolation_example-concurrent-transactions"></a>

この例では、まずトランザクション 1 は USERS テーブルから行を削除し、テーブルを再ロードします。次に COUNT(\$1) クエリを実行し、ANALYZE を実行してからコミットします。

```
begin;
delete one row from USERS table;
copy ;
select count(*) from users;
analyze ;
end;
```

その間、トランザクション 2 が開始します。このトランザクションは USERS テーブルへの追加行のコピー、テーブルの分析、最初のトランザクションと同じ COUNT(\$1) クエリの実行を試行します。

```
begin;
[waits]
copy users from ...;
select count(*) from users;
analyze;
end;
```

2 つ目のトランザクションは最初のトランザクションの完了を待つため、成功します。その COUNT クエリはそれが完了したロードに基づいてカウントを返します。

## スナップショット分離を使用した同時書き込みの例
<a name="r_Serializable_isolation_example-snapshot"></a>

### スナップショット分離を使用した同じテーブルへの同時 COPY オペレーション
<a name="r_Serializable_isolation_example-concurrent-copy-operations-into-the-same-table-snapshot"></a>

トランザクション 1 は LISTING テーブルに行をコピーします:

```
begin;
copy listing from ...;
end;
```

トランザクション 2 は別のセッションで同時に開始され、さらに多くの行を LISTING テーブルにコピーしようとします。トランザクション 2 は、いずれかのトランザクションがターゲットテーブル `listing` にデータを書き込む必要があるまで同時に進行できます。その時点では、トランザクションは順番に実行されます。

```
begin; 
//When the COPY statement from T1 needs to write data to the table, the COPY statement from T2 waits.
copy listing from ...; 
end;
```

片方または両方のトランザクションに COPY コマンドの代わりに INSERT コマンドが含まれる場合、同じ動作が起こることがあります。

### スナップショット分離を使用した同じテーブルからの同時 DELETE オペレーション
<a name="r_Serializable_isolation_example-concurrent-delete-operations-from-the-same-table-snapshot"></a>

スナップショット分離を使用した同じテーブルからの同時 DELETE または UPDATE オペレーションは、直列化可能な分離を使用したオペレーションと同じ方法で実行されます。

### スナップショット分離を使用した読み取りオペレーションと書き込みオペレーションがミックスされた同時トランザクション
<a name="r_Serializable_isolation_example-concurrent-transactions-snapshot"></a>

スナップショット分離を使用したオペレーションがミックスされた同時トランザクションは、直列化可能な分離を使用したオペレーションがミックスされたトランザクションと同じ方法で実行されます。

# 直列化可能な分離エラーのトラブルシューティング
<a name="c_serial_isolation-serializable-isolation-troubleshooting"></a>

## エラー: 1023 詳細: Redshift テーブルで直列化可能分離に関する違反が発生しました
<a name="c_serial_isolation-serialization-isolation-1023"></a>

Amazon Redshift で直列化可能な分離エラーが検出されると、次のようなエラーメッセージが表示されます。

```
ERROR:1023 DETAIL: Serializable isolation violation on table in Redshift
```

直列化可能な分離エラーに対処するには、次の方法をお試しください。
+ キャンセルされたトランザクションを再試行します。

   Amazon Redshift は、同時ワークロードがシリアル化できないことを検出しました。これは、アプリケーションのロジックにギャップがあることを示唆しています。通常、エラーが発生したトランザクションを再試行することで回避できます。問題が解決しない場合は、他のいずれかの方法をお試しください。
+ 同じアトミックトランザクション内にある不要なオペレーションは、トランザクション外に移動します。

  この方法は、2 つのトランザクション内の個々のオペレーションが、他のトランザクションの結果に影響を及ぼす可能性のある方法で相互参照する場合に適用されます。例えば、次の 2 つのセッションはそれぞれトランザクションを開始します。

  ```
  Session1_Redshift=# begin;
  ```

  ```
  Session2_Redshift=# begin;
  ```

  各トランザクションの SELECT ステートメントの結果は、もう一方の INSERT ステートメントの影響を受ける可能性があります。つまり、次のステートメントを任意の順序で連続して実行するとします。いずれの場合でも、結果として、トランザクションが同時に実行された場合よりも、SELECT ステートメントで 1 行多く返ります。同時実行の場合と同じ結果を生成するオペレーションを連続して実行できる順序はありません。そのため、最後に実行されるオペレーションは、直列化可能な分離エラーになります。

  ```
  Session1_Redshift=# select * from tab1;
  Session1_Redshift=# insert into tab2 values (1);
  ```

  ```
  Session2_Redshift=# insert into tab1 values (1);
  Session2_Redshift=# select * from tab2;
  ```

  多くの場合、SELECT ステートメントの結果は重要ではありません。つまり、トランザクション内のオペレーションのアトミック性は重要ではありません。これらの場合、次の例に示すように、トランザクションの外で SELECT ステートメントを移動します。

  ```
  Session1_Redshift=# begin;
  Session1_Redshift=# insert into tab1 values (1)
  Session1_Redshift=# end;
  Session1_Redshift=# select * from tab2;
  ```

  ```
  Session2_Redshift # select * from tab1;
  Session2_Redshift=# begin;
  Session2_Redshift=# insert into tab2 values (1)
  Session2_Redshift=# end;
  ```

  これらの例では、トランザクションに相互参照はありません。2 つの INSERT ステートメントは相互に影響しません。これらの例では、トランザクションを連続して実行し、同時に実行する場合と同じ結果を生成できる順序が少なくとも 1 つあります。つまり、このトランザクションは直列化可能です。
+ 直列化を適用するには、各セッションですべてのテーブルをロックします。

  [LOCK](r_LOCK.md) コマンドでは、直列化可能な分離エラーを引き起こす可能性のあるオペレーションをブロックします。LOCK コマンドを使用するときは、次の点を確認してください。
  + トランザクション内の読み取り専用 SELECT ステートメントの影響を受けるテーブルなど、トランザクションの影響を受けるすべてのテーブルをロックします。
  + オペレーションが実行される順序に関係なく、テーブルを同じ順序でロックします。
  + オペレーションを実行する前に、トランザクションの開始時にすべてのテーブルをロックします。
+ 同時実行トランザクションにはスナップショット分離を使用します。

  スナップショット分離で ALTER DATABASE コマンドを使用します。ALTER DATABASE の SNAPSHOT パラメータの詳細については、「[パラメータ](r_ALTER_DATABASE.md#r_ALTER_DATABASE-parameters)」を参照してください。

## エラー: 1018 詳細: リレーションが存在しません
<a name="c_serial_isolation-serialization-isolation-1018"></a>

Amazon Redshift オペレーションの同時実行を異なるセッションで行うと、次のようなエラーメッセージが表示されます。

```
ERROR: 1018 DETAIL: Relation does not exist.
```

Amazon Redshift のトランザクションは、スナップショットの分離に従います。トランザクションが開始されると、Amazon Redshift はデータベースのスナップショットを作成します。トランザクションのライフサイクル全体で、トランザクションはスナップショットに反映されているデータベースの状態で動作します。トランザクションがスナップショットに存在しないテーブルから読み込む場合、前に示した 1018 エラーメッセージをスローします。トランザクションがスナップショットを取得した後に別の並行トランザクションがテーブルを作成した場合でも、トランザクションは新しく作成されたテーブルから読み込むことができません。

このシリアル化分離エラーに対処するには、テーブルが存在することがわかっている時点にトランザクションの開始を移動してみてください。

テーブルが別のトランザクションによって作成された場合、この時点は、少なくともそのトランザクションがコミットされた後です。また、テーブルを削除した可能性のある同時トランザクションがコミットされていないことを確認します。

```
session1 = # BEGIN;
session1 = # DROP TABLE A;
session1 = # COMMIT;
```

```
session2 = # BEGIN;
```

```
session3 = # BEGIN;
session3 = # CREATE TABLE A (id INT);
session3 = # COMMIT;
```

```
session2 = # SELECT * FROM A;
```

そのため、session2 によって読み込みオペレーションとして最後に実行されるオペレーションは、直列化可能な分離エラーになります。このエラーは、session2 がスナップショットを取得し、コミットされた session1 によってテーブルがすでに削除されている場合に発生します。別の表現をすると、同時実行の session3 がテーブルを作成しても、それがスナップショット内にないため、session2 はそのテーブルを認識しません。

このエラーを解決するには、次のようにセッションを並べ替えます。

```
session1 = # BEGIN;
session1 = # DROP TABLE A;
session1 = # COMMIT;
```

```
session3 = # BEGIN;
session3 = # CREATE TABLE A (id INT);
session3 = # COMMIT;
```

```
session2 = # BEGIN;
session2 = # SELECT * FROM A;
```

session2 がスナップショットを取得するときに、session3 はすでにコミットされており、テーブルはデータベースにあります。Session2 は、エラーなしでテーブルから読み込むことができます。

# チュートリアル: Amazon S3 からデータをロードする
<a name="tutorial-loading-data"></a>

このチュートリアルでは、Amazon S3 バケット内のデータファイルから Amazon Redshift データベースのテーブルに、データを最初から最後までロードする手順を説明します。

このチュートリアルでは、以下の作業を行います。
+ コンマ区切り (CSV) 形式、文字区切り形式、固定幅形式のデータファイルをダウンロードします。
+ Amazon S3 バケットを作成し、データファイルをバケットにアップロードします。
+ Amazon Redshift クラスターを起動し、データベーステーブルを作成します。
+ COPY コマンドを使用して、Amazon S3 のデータファイルからテーブルをロードします。
+ ロードエラーをトラブルシューティングし、COPY コマンドを変更してエラーを修正します。

## 前提条件
<a name="tutorial-loading-data-prerequisites"></a>

次の前提条件を満たしている必要があります。
+ Amazon Redshift クラスターを起動し、Amazon S3 でバケットを作成するための AWS アカウント。
+ Amazon S3 からテストデータをロードするための AWS 認証情報 (IAM ロール)。新しい IAM ロールが必要な場合は、「[IAM ロールの作成](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create.html)」を参照してください。
+ Amazon Redshift コンソールクエリエディタなどの SQL クライアント。

このチュートリアルはそれだけで実行できるように設計されています。このチュートリアルに加えて Amazon Redshift データベースを設計および使用方法の詳細を理解するには、以下のチュートリアルを完了することをお勧めします。
+ [Amazon Redshift 入門ガイド](https://docs.aws.amazon.com/redshift/latest/gsg/)では、Amazon Redshift クラスターを作成してサンプルデータをロードするプロセスについて説明します。

## 概要
<a name="tutorial-loading-data-overview"></a>

INSERT コマンドを使用するか、または COPY コマンドを使用することで、Amazon Redshift テーブルにデータを追加できます。Amazon Redshift データウェアハウスの規模とスピードでは、COPY コマンドの方が INSERT コマンドよりも何倍も高速で、より効率的です。

COPY コマンドは Amazon Redshift の超並列処理 (MPP) アーキテクチャを使用し、複数のデータソースからデータを並列で読み込んでロードします。Amazon S3 のデータファイル、Amazon EMR、または Secure Shell (SSH) 接続でアクセス可能なリモートホストからロードできます。あるいは Amazon DynamoDB テーブルから直接ロードできます。

このチュートリアルでは、COPY コマンドを使用して Amazon S3 からデータをロードします。ここで示す原則の多くは、他のデータソースからのロードにも適用されます。

COPY コマンドの使用の詳細については、次のリソースを参照してください。
+ [データをロードするための Amazon Redshift のベストプラクティス](c_loading-data-best-practices.md)
+ [Amazon EMR からのデータのロード](loading-data-from-emr.md)
+ [リモートホストからデータをロードする](loading-data-from-remote-hosts.md)
+ [Amazon DynamoDB テーブルからのデータのロード](t_Loading-data-from-dynamodb.md)

## ステップ 1: クラスターを作成する
<a name="tutorial-loading-data-launch-cluster"></a>

使用するクラスターがすでにある場合は、この手順を省略できます。

このチュートリアルの演習では、4 ノードクラスターを使用します。

**クラスターを作成するには**

1. AWS マネジメントコンソール にサインインして、[https://console.aws.amazon.com/redshiftv2/](https://console.aws.amazon.com/redshiftv2/) で Amazon Redshift コンソールを開きます。

   ナビゲーションメニューで **[プロビジョニングされたクラスターダッシュボード]** を選択します。
**重要**  
クラスターオペレーションを実行するために必要なアクセス許可を持っていることを確認してください。必要なアクセス許可の付与については、「[Amazon Redshift が AWS サービスにアクセスすることを許可する](https://docs.aws.amazon.com/redshift/latest/mgmt/authorizing-redshift-service.html)」を参照してください。

1. 右上で、クラスターを作成する AWS リージョンを選択します。このチュートリアルは、[**US West (Oregon) (米国西部 (オレゴン))**] を選択するためのものです。

1. ナビゲーションメニューで **[Clusters]** (クラスター)、**[Create cluster]** (クラスターを作成) の順に選択します。[**クラスターの作成**] ページが表示されます。

1. **[Create cluster]** (クラスターの作成) ページで、クラスターのパラメータを入力します。以下の値を除き、パラメータには自身が使用する値を選択します。
   + ノードタイプとして **dc2.large** を選択します。
   + **[Number of nodes]** (ノード数) には **4** を指定します。
   + [**クラスターパラメータ**] で、IAM ロールを [**Available IAM roles (使用可能な IAM ロール)**] から選択します。このロールは前もって作成したものであり、Amazon S3 へのアクセス権限を持っている必要があります。次に、**[Associate IAM role]** (IAM ロールのアソシエート) をクリックして、クラスターの**[Associated IAM roles]** (アソシエートされた IAM ロール) のリストに追加します。

1. **[クラスターを作成]** を選択します。

[Amazon Redshift 入門ガイド](https://docs.aws.amazon.com/redshift/latest/gsg/)の手順に従って、SQL クライアントからクラスターに接続し、その接続をテストします。使用開始の残りの手順を完了して、テーブルの作成、データのアップロード、サンプルクエリの試行を行う必要はありません。

## ステップ 2: データファイルをダウンロードする
<a name="tutorial-loading-data-download-files"></a>

このステップでは、コンピュータに一連のサンプルデータファイルをダウンロードします。次のステップでは、Amazon S3 バケットにファイルをアップロードします。

**データファイルをダウンロードするには**

1. zip ファイル [LoadingDataSampleFiles.zip](samples/LoadingDataSampleFiles.zip) をダウンロードします。

1. お使いのコンピュータのフォルダにファイルを展開します。

1. 以下のファイルがフォルダに含まれていることを確認します。

   ```
   customer-fw-manifest
   customer-fw.tbl-000
   customer-fw.tbl-000.bak
   customer-fw.tbl-001
   customer-fw.tbl-002
   customer-fw.tbl-003
   customer-fw.tbl-004
   customer-fw.tbl-005
   customer-fw.tbl-006
   customer-fw.tbl-007
   customer-fw.tbl.log
   dwdate-tab.tbl-000
   dwdate-tab.tbl-001
   dwdate-tab.tbl-002
   dwdate-tab.tbl-003
   dwdate-tab.tbl-004
   dwdate-tab.tbl-005
   dwdate-tab.tbl-006
   dwdate-tab.tbl-007
   part-csv.tbl-000
   part-csv.tbl-001
   part-csv.tbl-002
   part-csv.tbl-003
   part-csv.tbl-004
   part-csv.tbl-005
   part-csv.tbl-006
   part-csv.tbl-007
   ```

## ステップ 3: Amazon S3 バケットにファイルをアップロードする
<a name="tutorial-loading-data-upload-files"></a>

このステップでは、Amazon S3 バケットを作成し、データファイルをバケットにアップロードします。

### 
<a name="tutorial-loading-data-to-upload-files"></a>

**Amazon S3 バケットにファイルをアップロードするには**

1. Amazon S3 にバケットを作成します。

   バケットの作成の詳細については、「*Amazon Simple Storage Service ユーザーガイド*」の「[バケットの作成](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)」を参照してください。

   1. AWS マネジメントコンソール にサインインし、Amazon S3 コンソール ([https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)) を開きます。

   1. **バケットの作成** を選択します。

   1. [] を選択しますAWS リージョン 

      クラスターと同じリージョンでバケットを作成します。使用しているクラスターが米国西部 (オレゴン) リージョンにある場合は、**[US West (Oregon) Region (us-west-2)]** (米国西部 (オレゴン) リージョン (us-west-2)) を選択します。

   1. **[バケットを作成]** ダイアログボックスの **[バケット名]** ボックスに、バケットの名前を入力します。

      バケット名は必ず、Amazon S3 内の既存バケット名の中で一意となるようにしてください。一意性を確実にする方法の 1 つは、バケット名を組織名で始めることです。バケット名は一定の規則に沿って命名する必要があります。詳細については、*Amazon Simple Storage Service ユーザーガイド*の[バケットの制約と制限](https://docs.aws.amazon.com/AmazonS3/latest/userguide/BucketRestrictions.html)を参照してください。

   1. 残りのオプションについては、推奨デフォルトを選択します。

   1. **[バケットを作成する]** を選択します。

      Amazon S3 が正常にバケットを作成すると、コンソールが [**Buckets (バケット)**] パネルに空のバケットを表示します。

1. フォルダを作成します。

   1. 新しいバケットの名前を選択します。

   1. **[フォルダを作成]** ボタンを選択します。

   1. 新しいフォルダに **load** という名前を付けます。
**注記**  
作成したバケットは、サンドボックスの中にはありません。この演習では、実際のバケットにオブジェクトを追加します。オブジェクトをバケットに格納する時間に対して、名目上の料金が発生します。Amazon S3 の料金に関する詳細については、[Amazon S3 の料金](https://aws.amazon.com/s3/pricing/)を参照してください。

1. データファイルを新しい Amazon S3 バケットにアップロードします。

   1. データフォルダの名前を選択します。

   1. [アップロード] ウィザードで、**[ファイルを追加]** をクリックします。

      Amazon S3 コンソールの指示に従い、ダウンロードおよび展開したすべてのファイルをアップロードします。

   1. **アップロード** を選択します。
<a name="tutorial-loading-user-credentials"></a>
**ユーザー認証情報**  
Amazon Redshift の COPY コマンドでは、Amazon S3 バケットにあるファイルオブジェクトを読み込むためのアクセス権が必要です。Amazon S3 バケットを作成したときと同じユーザー認証情報を使用して Amazon Redshift の COPY コマンドを実行する場合、COPY コマンドには必要なすべてのアクセス許可があります。異なるユーザーの認証情報を使用する場合は、Amazon S3 のアクセスコントロールを使用して、アクセスを許可できます。Amazon Redshift の COPY コマンドでは、Amazon S3 バケット内のファイルオブジェクトにアクセスするために、少なくとも ListBucket と GetObject のアクセス許可が必要です。Amazon S3 リソースへのアクセスコントロールの詳細については、[Amazon S3 リソースへのアクセス許可の管理](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html)を参照してください。

## ステップ 4: サンプルテーブルを作成する
<a name="tutorial-loading-data-create-tables"></a>

このチュートリアルでは、Star Schema Benchmark (SSB) スキーマに基づいた複数のテーブルをセットとして使用します。以下の図に示しているのは SSB データモデルです。

![\[SSB スキーマの 5 つのテーブルとその相互関係。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/tutorial-optimize-tables-ssb-data-model.png)


SSB テーブルは現在のデータベースにすでに存在している場合があります。その場合は、テーブルをドロップしてデータベースから削除してから、次の手順で CREATE TABLE コマンドを使用してテーブルを作成します。このチュートリアルで使用されるテーブルには、既存のテーブルとは異なる属性が含まれている可能性があります。

**サンプルテーブルを作成するには**

1. SSB テーブルをドロップするには、SQL クライアントで以下のコマンドを実行します。

   ```
   drop table part cascade;
   drop table supplier;
   drop table customer;
   drop table dwdate;
   drop table lineorder;
   ```

1. SQL クライアントで以下の CREATE TABLE コマンドを実行します。

   ```
   CREATE TABLE part 
   (
     p_partkey     INTEGER NOT NULL,
     p_name        VARCHAR(22) NOT NULL,
     p_mfgr        VARCHAR(6),
     p_category    VARCHAR(7) NOT NULL,
     p_brand1      VARCHAR(9) NOT NULL,
     p_color       VARCHAR(11) NOT NULL,
     p_type        VARCHAR(25) NOT NULL,
     p_size        INTEGER NOT NULL,
     p_container   VARCHAR(10) NOT NULL
   );
   
   CREATE TABLE supplier 
   (
     s_suppkey   INTEGER NOT NULL,
     s_name      VARCHAR(25) NOT NULL,
     s_address   VARCHAR(25) NOT NULL,
     s_city      VARCHAR(10) NOT NULL,
     s_nation    VARCHAR(15) NOT NULL,
     s_region    VARCHAR(12) NOT NULL,
     s_phone     VARCHAR(15) NOT NULL
   );
   
   CREATE TABLE customer 
   (
     c_custkey      INTEGER NOT NULL,
     c_name         VARCHAR(25) NOT NULL,
     c_address      VARCHAR(25) NOT NULL,
     c_city         VARCHAR(10) NOT NULL,
     c_nation       VARCHAR(15) NOT NULL,
     c_region       VARCHAR(12) NOT NULL,
     c_phone        VARCHAR(15) NOT NULL,
     c_mktsegment   VARCHAR(10) NOT NULL
   );
   
   CREATE TABLE dwdate 
   (
     d_datekey            INTEGER NOT NULL,
     d_date               VARCHAR(19) NOT NULL,
     d_dayofweek          VARCHAR(10) NOT NULL,
     d_month              VARCHAR(10) NOT NULL,
     d_year               INTEGER NOT NULL,
     d_yearmonthnum       INTEGER NOT NULL,
     d_yearmonth          VARCHAR(8) NOT NULL,
     d_daynuminweek       INTEGER NOT NULL,
     d_daynuminmonth      INTEGER NOT NULL,
     d_daynuminyear       INTEGER NOT NULL,
     d_monthnuminyear     INTEGER NOT NULL,
     d_weeknuminyear      INTEGER NOT NULL,
     d_sellingseason      VARCHAR(13) NOT NULL,
     d_lastdayinweekfl    VARCHAR(1) NOT NULL,
     d_lastdayinmonthfl   VARCHAR(1) NOT NULL,
     d_holidayfl          VARCHAR(1) NOT NULL,
     d_weekdayfl          VARCHAR(1) NOT NULL
   );
   CREATE TABLE lineorder 
   (
     lo_orderkey          INTEGER NOT NULL,
     lo_linenumber        INTEGER NOT NULL,
     lo_custkey           INTEGER NOT NULL,
     lo_partkey           INTEGER NOT NULL,
     lo_suppkey           INTEGER NOT NULL,
     lo_orderdate         INTEGER NOT NULL,
     lo_orderpriority     VARCHAR(15) NOT NULL,
     lo_shippriority      VARCHAR(1) NOT NULL,
     lo_quantity          INTEGER NOT NULL,
     lo_extendedprice     INTEGER NOT NULL,
     lo_ordertotalprice   INTEGER NOT NULL,
     lo_discount          INTEGER NOT NULL,
     lo_revenue           INTEGER NOT NULL,
     lo_supplycost        INTEGER NOT NULL,
     lo_tax               INTEGER NOT NULL,
     lo_commitdate        INTEGER NOT NULL,
     lo_shipmode          VARCHAR(10) NOT NULL
   );
   ```

## ステップ 5: COPY コマンドを実行する
<a name="tutorial-loading-run-copy"></a>

COPY コマンドを実行して、SSB のスキーマの各テーブルをロードします。この COPY コマンドの例は、さまざまなファイル形式からのロード、COPY コマンドのオプションの使用、およびロードエラーのトラブルシューティングの方法を示しています。

### COPY コマンドの構文
<a name="tutorial-loading-data-copy-syntax"></a>

基本的な [COPY](r_COPY.md) コマンドの構文は次のとおりです。

```
COPY table_name [ column_list ] FROM data_source CREDENTIALS access_credentials [options] 
```

COPY コマンドを実行するには、以下の値を指定します。
<a name="tutorial-loading-syntax-table-name"></a>
**テーブル名**  
COPY コマンドのターゲットテーブル。テーブルはすでにデータベースに存在する必要があります。テーブルは一時テーブルまたは永続的テーブルです。COPY コマンドは、新しい入力データをテーブルの既存の行に追加します。
<a name="tutorial-loading-syntax-column-list"></a>
**列リスト**  
デフォルトでは、COPY はソースデータのフィールドを順番にテーブルの列にロードします。オプションで、列名のカンマ区切りリストである*列リスト*を指定して、データフィールドを特定の列にマッピングすることができます。このチュートリアルでは列リストは使用しません。詳細については、COPY コマンドのリファレンスの「[Column List](copy-parameters-column-mapping.md#copy-column-list)」を参照してください。

<a name="tutorial-loading-syntax-data-source.title"></a>データソース

COPY コマンドを使用して、Amazon S3 バケット、Amazon EMR クラスター、リモート ホスト (SSH 接続を使用)、または Amazon DynamoDB テーブルからデータをロードできます。このチュートリアルでは、Amazon S3 バケットのデータファイルからロードします。Amazon S3 からロードする際、バケット名とデータファイルの場所を指定する必要があります。これを行うには、データファイルのオブジェクトパス、または各データファイルとその場所を明示的に一覧表示するマニフェストファイルの場所を指定します。
+ キープレフィックス 

  Amazon S3 に保存されたオブジェクトはオブジェクトキーによって一意に識別されます。オブジェクトキーには、バケット名、フォルダ名 (存在する場合)、およびオブジェクト名が含まれます。*キープレフィックス*は、同じプレフィックスを持つ一連のオブジェクトを指します。オブジェクトパスは、キープレフィックスを共有するすべてのオブジェクトをロードするために、COPY コマンドで使用するキープレフィックスです。例えば、キープレフィックス `custdata.txt` は、単一のファイルを指す場合も、`custdata.txt.001`、`custdata.txt.002` など、一連のファイルを指す場合もあります。
+ マニフェストファイル

  場合によっては、複数のバケットやフォルダなどから、異なる接頭辞を持つファイルをロードする必要があります。また、接頭辞を共有するファイルを除外する必要がある場合もあります。これらの場合には、マニフェストファイルを使用できます。*マニフェストファイル*は、ロードする各ファイルとその一意のオブジェクトキーを明示的にリストします。このチュートリアルでは、マニフェストファイルを使用して PART テーブルをロードします。
<a name="tutorial-loading-syntax-credentials"></a>
**認証情報**  
ロードするデータが格納されている AWS リソースにアクセスするには、十分な権限を持つユーザーの AWS アクセス認証情報を指定する必要があります。これらの認証情報には IAM ロール の Amazon リソースネーム (ARN) が含まれます。Amazon S3 からデータをロードするには、認証情報に ListBucket と GetObject のアクセス許可が含まれている必要があります。データが暗号化されている場合は、追加の認証情報が必要です。詳細については、COPY コマンドのリファレンスの「[認可パラメータ](copy-parameters-authorization.md)」を参照してください。アクセスの管理の詳細については、[Amazon S3 リソースへの許可の管理](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html)を参照してください。

<a name="tutorial-loading-syntax-options.title"></a>オプション

COPY コマンドで多くのパラメータを指定することによって、ファイル形式の指定、データ形式の管理、エラーの管理、およびその他の機能の制御を行うことができます。このチュートリアルでは、次のような COPY コマンドのオプションおよび機能を使用します。
+ キープレフィックス

  キープレフィックスを指定して複数のファイルからロードする方法については、「[NULL AS を使用した PART テーブルのロード](#tutorial-loading-load-part)」を参照してください。
+ CSV 形式

  CSV 形式のデータをロードする方法については、「[NULL AS を使用した PART テーブルのロード](#tutorial-loading-load-part)」を参照してください。
+ NULL AS

  NULL AS オプションを使用して PART をロードする方法については、「[NULL AS を使用した PART テーブルのロード](#tutorial-loading-load-part)」を参照してください。
+ 文字区切り形式

  DELIMITER オプションの使用方法については、「[DELIMITER オプションと REGION オプション](#tutorial-loading-load-supplier)」を参照してください。
+ REGION

  REGION オプションの使用方法については、「[DELIMITER オプションと REGION オプション](#tutorial-loading-load-supplier)」を参照してください。
+ 固定幅形式

  固定幅データから CUSTOMER テーブルをロードする方法については、「[MANIFEST を使用した CUSTOMER テーブルのロード](#tutorial-loading-load-customer)」を参照してください。
+ MAXERROR

  MAXERROR オプションの使用方法については、「[MANIFEST を使用した CUSTOMER テーブルのロード](#tutorial-loading-load-customer)」を参照してください。
+ ACCEPTINVCHARS

  ACCEPTINVCHARS オプションの使用方法については、「[MANIFEST を使用した CUSTOMER テーブルのロード](#tutorial-loading-load-customer)」を参照してください。
+ MANIFEST

  MANIFEST オプションの使用方法については、「[MANIFEST を使用した CUSTOMER テーブルのロード](#tutorial-loading-load-customer)」を参照してください。
+ DATEFORMAT

  DATEFORMAT オプションの使用方法については、「[DATEFORMAT を使用した DWDATE テーブルのロード](#tutorial-loading-load-dwdate)」を参照してください。
+ GZIP、LZOP および BZIP2

  ファイルを圧縮する方法については、「[複数のデータファイルをロードする](#tutorial-loading-load-lineorder)」を参照してください。
+ COMPUPDATE

  COMPUPDATE オプションの使用方法については、「[複数のデータファイルをロードする](#tutorial-loading-load-lineorder)」を参照してください。
+ 複数のファイル

  複数のファイルをロードする方法については、「[複数のデータファイルをロードする](#tutorial-loading-load-lineorder)」を参照してください。

### SSB テーブルのロード
<a name="tutorial-loading-run-copy-load-tables"></a>

SSB スキーマの各テーブルをロードするには、次の COPY コマンドを使用します。各テーブルに対するコマンドは、COPY のさまざまなオプションとトラブルシューティングの手法を示しています。

SSB テーブルをロードするには、以下の手順に従います。

1. [バケット名と AWS 認証情報を置き換える](#tutorial-loading-run-copy-replaceables)

1. [NULL AS を使用した PART テーブルのロード](#tutorial-loading-load-part)

1. [MANIFEST を使用した CUSTOMER テーブルのロード](#tutorial-loading-load-customer)

1. [DATEFORMAT を使用した DWDATE テーブルのロード](#tutorial-loading-load-dwdate)

#### バケット名と AWS 認証情報を置き換える
<a name="tutorial-loading-run-copy-replaceables"></a>

このチュートリアルの COPY コマンドは次の形式で表示されます。

```
copy table from 's3://<your-bucket-name>/load/key_prefix' 
credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>'
options;
```

各 COPY コマンドで、以下の作業を行います。

1. *<your-bucket-name>* を、お使いのクラスターと同じリージョンにあるバケットの名前に置き換えます。

   このステップでは、バケットとクラスターが同じリージョンにあることを前提としています。代わりに、COPY コマンドで [REGION](copy-parameters-data-source-s3.md#copy-region) オプションを使用してリージョンを指定できます。

1. *<aws-account-id>* および *<role-name>* は、使用している AWS アカウント ならびに IAM ロールに置き換えます。一重引用符で囲まれた認証情報文字列に、スペースまたは改行を含めることはできません。ARN の形式はサンプルとは多少異なる場合があることに注意してください。COPY コマンドを実行するときは、正しい ARN を使用するために、IAM コンソールからロールの ARN をコピーすることをお勧めします。

#### NULL AS を使用した PART テーブルのロード
<a name="tutorial-loading-load-part"></a>

このステップでは、CSV オプションと NULL AS オプションを使用して、PART テーブルをロードします。

COPY コマンドでは、複数のファイルから並列してデータをロードでき、1 つのファイルからロードする場合よりも高速です。この原理を示すために、このチュートリアルでは、ファイルは非常に小さくなりますが、各テーブルのデータを 8 個のファイルに分割しています。後のステップで、1 つのファイルからのロードと複数のファイルからのロードとの時間の差を比較します。詳細については、「[データファイルをロードする](c_best-practices-use-multiple-files.md)」を参照してください。
<a name="tutorial-loading-key-prefix"></a>
**キープレフィックス**  
ファイルセットのキープレフィックスを指定するか、マニフェストファイルにファイルのリストを明示的に指定することで、複数のファイルからロードできます。このステップでは、キープレフィックスを使用します。後のステップでは、マニフェストファイルを使用します。キープレフィックス `'s3://amzn-s3-demo-bucket/load/part-csv.tbl'` によって、`load` フォルダ内の以下のファイルのセットがロードされます。

```
part-csv.tbl-000
part-csv.tbl-001
part-csv.tbl-002
part-csv.tbl-003
part-csv.tbl-004
part-csv.tbl-005
part-csv.tbl-006
part-csv.tbl-007
```
<a name="tutorial-loading-csv-format"></a>
**CSV 形式**  
CSV は、カンマ区切り値を意味し、スプレッドシートのデータをインポートおよびエクスポートする際に使用される一般的な形式です。CSV では、フィールド内に引用符で囲まれた文字列を含めることができるため、カンマ区切り形式よりも柔軟です。CSV 形式から COPY を実行する場合、デフォルトの引用文字は二重引用符 ( " ) ですが、QUOTE AS オプションを使用して別の引用文字を指定できます。フィールド内で引用符文字を使用する場合は、追加の引用符文字で文字をエスケープしてください。

PART テーブルの CSV 形式のデータファイルから抜粋した次のデータは、二重引用符で囲まれた文字列 (`"LARGE ANODIZED BRASS"`) を示しています。また、引用符で囲まれた文字列内の 2 つの二重引用符で囲まれた文字列 (`"MEDIUM ""BURNISHED"" TIN"`) が表示されます。

```
15,dark sky,MFGR#3,MFGR#47,MFGR#3438,indigo,"LARGE ANODIZED BRASS",45,LG CASE
22,floral beige,MFGR#4,MFGR#44,MFGR#4421,medium,"PROMO, POLISHED BRASS",19,LG DRUM
23,bisque slate,MFGR#4,MFGR#41,MFGR#4137,firebrick,"MEDIUM ""BURNISHED"" TIN",42,JUMBO JAR
```

PART テーブルのデータには、COPY が失敗する原因となる文字が含まれています。この演習では、エラーをトラブルシューティングし、修正します。

形式のデータをロードするには、COPY コマンド に `csv`csv を追加 します。以下のコマンドを実行して、PART テーブルをロードします。

```
copy part from 's3://<your-bucket-name>/load/part-csv.tbl' 
credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>'
csv;
```

次のようなエラーメッセージが表示されます。

```
An error occurred when executing the SQL command:
copy part from 's3://amzn-s3-demo-bucket/load/part-csv.tbl' 
credentials' ...

ERROR: Load into table 'part' failed.  Check 'stl_load_errors' system table for details. [SQL State=XX000] 

Execution time: 1.46s

1 statement(s) failed.
1 statement(s) failed.
```

エラーに関する詳細情報を取得するには、STL\$1LOAD\$1ERRORS テーブルに対してクエリを実行します。次のクエリでは、列を短縮して読みやすくするために SUBSTRING 関数を使用し、返される行数を減らすために LIMIT 10 を使用しています。バケット名の長さに合わせて、`substring(filename,22,25)` の値を調整できます。

```
select query, substring(filename,22,25) as filename,line_number as line, 
substring(colname,0,12) as column, type, position as pos, substring(raw_line,0,30) as line_text,
substring(raw_field_value,0,15) as field_text, 
substring(err_reason,0,45) as reason
from stl_load_errors 
order by query desc
limit 10;
```

```
 query  |    filename      | line |  column   |    type    | pos |      
--------+-------------------------+-----------+------------+------------+-----+----
 333765 | part-csv.tbl-000 |    1 |           |            |   0 |

 line_text        | field_text |                    reason
------------------+------------+----------------------------------------------
 15,NUL next,     |            | Missing newline: Unexpected character 0x2c f
```
<a name="tutorial-loading-null-as"></a>
**NULL AS**  
`part-csv.tbl` データファイルでは、NUL ターミネータ文字 (`\x000` または `\x0`) を使用して NULL 値を表します。

**注記**  
スペルやよく似ていますが、NUL と NULL は同じではありません。NUL は、コードポイントが `x000` である UTF-8 文字で、通常、レコードの終わり (EOR) を示すために使用されます。NULL はデータがないことを表す SQL 値です。

デフォルトでは、COPY は NUL ターミネータ文字を EOR 文字として処理し、レコードを終了します。これは通常、予期しない結果やエラーが発生する原因となります。テキストデータで NULL を示す標準的な方法はありません。したがって、NULL AS COPY コマンドオプションを使用すると、テーブルのロード時に NULL で置換する文字を指定できます。この例では、COPY で、NUL ターミネータ文字を NULL 値として処理する必要があります。

**注記**  
NULL 値を受け取るテーブルの列は、*NULL が許容される*ように設定されている必要があります。つまり、CREATE TABLE の指定に NOT NULL 制約を含めないようにする必要があります。

NULL AS オプションを使って PART をロードするには、以下の COPY コマンドを実行します。

```
copy part from 's3://<your-bucket-name>/load/part-csv.tbl' 
credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>' 
csv
null as '\000';
```

COPY によって NULL 値がロードされたことを確認するには、以下のコマンドを実行して NULL が含まれる行のみを選択します。

```
select p_partkey, p_name, p_mfgr, p_category from part where p_mfgr is null;
```

```
 p_partkey |  p_name  | p_mfgr | p_category
-----------+----------+--------+------------
        15 | NUL next |        | MFGR#47
        81 | NUL next |        | MFGR#23
       133 | NUL next |        | MFGR#44 
(2 rows)
```

#### DELIMITER オプションと REGION オプション
<a name="tutorial-loading-load-supplier"></a>

DELIMITER オプションと REGION オプションは、データのロード方法を理解するために重要です。
<a name="tutorial-loading-character-delimited-format"></a>
**文字区切り形式**  
文字区切りファイルのフィールドは、パイプ文字 ( \$1 )、カンマ ( , )、タブ ( \$1t ) など、特定の文字で区切られます。文字区切りファイルでは、区切り記号として、非表示の ASCII 文字を含め、任意の ASCII 文字 1 文字を使用できます。DELIMITER オプションを使用して区切り文字を指定できます。デフォルトの区切り文字はパイプ文字です。

SUPPLIER テーブルから抜粋した次のデータでは、パイプ区切り形式を使用しています。

```
1|1|257368|465569|41365|19950218|2-HIGH|0|17|2608718|9783671|4|2504369|92072|2|19950331|TRUCK
1|2|257368|201928|8146|19950218|2-HIGH|0|36|6587676|9783671|9|5994785|109794|6|19950416|MAIL
```
<a name="tutorial-loading-region"></a>
**REGION**  
可能な限り、ロードデータは Amazon Redshift クラスターと同じ AWS リージョンに配置してください。データとクラスターが同じリージョンにある場合、レイテンシーが短縮され、リージョン間のデータ転送のコストを回避できます。詳細については、「[データをロードするための Amazon Redshift のベストプラクティス](c_loading-data-best-practices.md)」を参照してください。

別の AWS リージョンからデータをロードする必要がある場合は、REGION オプションを使用して、そのロードデータが配置されている AWS リージョンを指定します。リージョンを指定する場合は、マニフェストファイルを含むすべてのロードデータが、指定されたリージョンに存在している必要があります。詳細については、「[REGION](copy-parameters-data-source-s3.md#copy-region)」を参照してください。

例えば、クラスターが米国東部 (バージニア北部) リージョンにあり、Amazon S3 バケットが米国西部 (オレゴン) リージョンにある場合は、次の COPY コマンドでパイプ区切りデータから SUPPLIER テーブルをロードできます。

```
copy supplier from 's3://amzn-s3-demo-bucket/ssb/supplier.tbl' 
credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>' 
delimiter '|' 
gzip
region 'us-west-2';
```

#### MANIFEST を使用した CUSTOMER テーブルのロード
<a name="tutorial-loading-load-customer"></a>

このステップでは、FIXEDWIDTH、MAXERROR、ACCEPTINVCHARS、および MANIFEST オプションを使用して、CUSTOMER テーブルをロードします。

この演習のサンプルデータには、COPY でロードしようとしたときにエラーの原因となる文字が含まれています。MAXERRORS オプションと STL\$1LOAD\$1ERRORS システムテーブルを使用してロードエラーのトラブルシューティングを行い、次に ACCEPTINVCHARS オプションと MANIFEST オプションを使用してエラーを排除します。
<a name="tutorial-loading-fixed-width"></a>
**固定幅形式**  
固定幅形式は、区切り記号でフィールドを分離するのではなく、各フィールドを固定文字数で定義します。CUSTOMER テーブルから抜粋した次のデータでは、固定幅形式を使用しています。

```
1   Customer#000000001   IVhzIApeRb           MOROCCO  0MOROCCO  AFRICA      25-705 
2   Customer#000000002   XSTf4,NCwDVaWNe6tE   JORDAN   6JORDAN   MIDDLE EAST 23-453
3   Customer#000000003   MG9kdTD              ARGENTINA5ARGENTINAAMERICA     11-783
```

ラベル/幅のペアの順序はテーブルの列の順序に正確に一致する必要があります。詳細については、「[FIXEDWIDTH](copy-parameters-data-format.md#copy-fixedwidth)」を参照してください。

CUSTOMER テーブルのデータの固定幅指定文字列は、次のとおりです。

```
fixedwidth 'c_custkey:10, c_name:25, c_address:25, c_city:10, c_nation:15, 
c_region :12, c_phone:15,c_mktsegment:10'
```

固定幅データから CUSTOMER テーブルをロードするには、以下のコマンドを実行します。

```
copy customer
from 's3://<your-bucket-name>/load/customer-fw.tbl'
credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>' 
fixedwidth 'c_custkey:10, c_name:25, c_address:25, c_city:10, c_nation:15, c_region :12, c_phone:15,c_mktsegment:10';
```

次のようなエラーメッセージが表示されます。

```
An error occurred when executing the SQL command:
copy customer
from 's3://amzn-s3-demo-bucket/load/customer-fw.tbl'
credentials'...

ERROR: Load into table 'customer' failed.  Check 'stl_load_errors' system table for details. [SQL State=XX000] 

Execution time: 2.95s

1 statement(s) failed.
```
<a name="tutorial-loading-maxerror"></a>
**MAXERROR**  
デフォルトでは、COPY で最初にエラーが発生したときに、コマンドは失敗し、エラーメッセージを返します。テスト中は時間を節約するために、MAXERROR オプションを使用して、失敗する前に指定した数のエラーをスキップするように COPY に指示できます。CUSTOMER テーブルのデータのロードを最初にテストするときにはエラーが予想されるため、COPY コマンドに `maxerror 10` を追加します。

FIXEDWIDTH オプションと MAXERROR オプションを使用してテストするには、以下のコマンドを実行します。

```
copy customer
from 's3://<your-bucket-name>/load/customer-fw.tbl'
credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>' 
fixedwidth 'c_custkey:10, c_name:25, c_address:25, c_city:10, c_nation:15, c_region :12, c_phone:15,c_mktsegment:10'
maxerror 10;
```

今回は、エラーメッセージの代わりに、次のような警告メッセージが表示されます。

```
Warnings:
Load into table 'customer' completed, 112497 record(s) loaded successfully.
Load into table 'customer' completed, 7 record(s) could not be loaded.  Check 'stl_load_errors' system table for details.
```

この警告は、COPY で 7 個のエラーが発生したことを示します。エラーを確認するには、次の例のように、STL\$1LOAD\$1ERRORS テーブルに対してクエリを実行します。

```
select query, substring(filename,22,25) as filename,line_number as line, 
substring(colname,0,12) as column, type, position as pos, substring(raw_line,0,30) as line_text,
substring(raw_field_value,0,15) as field_text, 
substring(err_reason,0,45) as error_reason
from stl_load_errors 
order by query desc, filename 
limit 7;
```

STL\$1LOAD\$1ERRORS のクエリの結果は次のようになるはずです。

```
 query  |         filename          | line |  column   |    type    | pos |           line_text           | field_text |              error_reason
--------+---------------------------+------+-----------+------------+-----+-------------------------------+------------+----------------------------------------------
 334489 | customer-fw.tbl.log       |    2 | c_custkey | int4       |  -1 | customer-fw.tbl               | customer-f | Invalid digit, Value 'c', Pos 0, Type: Integ
 334489 | customer-fw.tbl.log       |    6 | c_custkey | int4       |  -1 | Complete                      | Complete   | Invalid digit, Value 'C', Pos 0, Type: Integ
 334489 | customer-fw.tbl.log       |    3 | c_custkey | int4       |  -1 | #Total rows                   | #Total row | Invalid digit, Value '#', Pos 0, Type: Integ
 334489 | customer-fw.tbl.log       |    5 | c_custkey | int4       |  -1 | #Status                       | #Status    | Invalid digit, Value '#', Pos 0, Type: Integ
 334489 | customer-fw.tbl.log       |    1 | c_custkey | int4       |  -1 | #Load file                    | #Load file | Invalid digit, Value '#', Pos 0, Type: Integ
 334489 | customer-fw.tbl000        |    1 | c_address | varchar    |  34 | 1         Customer#000000001  | .Mayag.ezR | String contains invalid or unsupported UTF8
 334489 | customer-fw.tbl000        |    1 | c_address | varchar    |  34 | 1         Customer#000000001  | .Mayag.ezR | String contains invalid or unsupported UTF8
(7 rows)
```

この結果を調べると、`error_reasons` 列に 2 件のメッセージがあることがわかります。
+ 

  ```
  Invalid digit, Value '#', Pos 0, Type: Integ 
  ```

  これらのエラーは、`customer-fw.tbl.log` ファイルによって発生しています。問題は、このファイルがデータファイルではなくログファイルであることです。このファイルがロードされないようにする必要があります。マニフェストファイルを使用して、誤ったファイルがロードされることを回避できます。
+ 

  ```
  String contains invalid or unsupported UTF8 
  ```

  VARCHAR データ型は、最大 3 バイトのマルチバイト UTF-8 文字をサポートします。ロードデータにサポートされていない文字や無効な文字が含まれている場合、ACCEPTINVCHARS オプションを使用して、すべての無効な文字を指定した代替文字に置き換えることができます。

負荷に関するもう一つの問題は、検出がより難しく、負荷が予期せぬ結果を生み出しました。この問題を調査するには、以下のコマンドを実行して、CUSTOMER テーブルをクエリします。

```
select c_custkey, c_name, c_address        
from customer
order by c_custkey
limit 10;
```

```
 c_custkey |          c_name           |         c_address
-----------+---------------------------+---------------------------
         2 | Customer#000000002        | XSTf4,NCwDVaWNe6tE
         2 | Customer#000000002        | XSTf4,NCwDVaWNe6tE
         3 | Customer#000000003        | MG9kdTD
         3 | Customer#000000003        | MG9kdTD
         4 | Customer#000000004        | XxVSJsL
         4 | Customer#000000004        | XxVSJsL
         5 | Customer#000000005        | KvpyuHCplrB84WgAi
         5 | Customer#000000005        | KvpyuHCplrB84WgAi
         6 | Customer#000000006        | sKZz0CsnMD7mp4Xd0YrBvx
         6 | Customer#000000006        | sKZz0CsnMD7mp4Xd0YrBvx
(10 rows)
```

行は一意である必要がありますが、重複があります。

予期しない結果を検証するもう 1 つの方法は、ロードされた行数を検証することです。今回のケースでは、100000 行がロードされているはずですが、ロードのメッセージには 112497 件のレコードがロードされたと示されています。ロードされた行が多いのは、COPY で余分なファイル `customer-fw.tbl0000.bak` がロードされたためです。

この演習では、マニフェストファイルを使用して、誤ったファイルがロードされることを回避します。
<a name="tutorial-loading-acceptinvchars"></a>
**ACCEPTINVCHARS**  
デフォルトでは、COPY は列のデータ型でサポートされていない文字を検出した場合、その行をスキップし、エラーを返します。無効な UTF-8 文字の詳細については、「[マルチバイト文字のロードエラー](multi-byte-character-load-errors.md)」を参照してください。

MAXERRORS オプションによってエラーを無視してロードを続行し、STL\$1LOAD\$1ERRORS にクエリを実行して無効な文字を特定した後、データファイルを修正できます。ただし、MAXERRORS はロードの問題のトラブルシューティングには最適ですが、一般的に、本番環境では使用しないでください。

ACCEPTINVCHARS オプションは、通常、無効な文字を管理するのに適しています。ACCEPTINVCHARS によって、無効な文字を指定した有効な文字で置き換え、ロード操作を続行することを COPY コマンドに指示します。置換文字として、NULL 以外の有効な ASCII 文字を指定できます。デフォルトの置換文字は疑問符 (?) です。COPY は、マルチバイト文字を同じ長さの置換文字列に置き換えます。例えば、4 バイト文字は `'????'` に置き換えられます。

COPY は、無効な UTF-8 文字を含む行の数を返します。また、影響を受ける行ごとに STL\$1REPLACEMENTS システムテーブルにエントリを追加します (ノードスライスあたり最大 100 行)。さらに多くの無効な UTF-8 文字も置き換えられますが、それらの置換イベントは記録されません。

ACCEPTINVCHARS は VARCHAR 列に対してのみ有効です。

このステップでは、ACCEPTINVCHARS と置換文字 `'^'` を追加します。
<a name="tutorial-loading-manifest"></a>
**MANIFEST**  
キープレフィックスを使用して Amazon S3 からの COPY を実行すると、不要なテーブルをロードするリスクがあります。例えば、`'s3://amzn-s3-demo-bucket/load/` フォルダには、キープレフィックス `customer-fw.tbl` を共有する 8 個のデータファイルが含まれます (`customer-fw.tbl0000`、`customer-fw.tbl0001` など)。ただし、同じフォルダには、余分なファイルである `customer-fw.tbl.log` や `customer-fw.tbl-0001.bak` も含まれています。

必要なすべてのファイル、および正しいファイルのみをロードするには、マニフェストファイルを使用します。マニフェストは JSON 形式のテキストファイルで、ロードされる各ソースファイルについて一意のオブジェクトキーを明示的にリストします。ファイルオブジェクトは、異なるフォルダや異なるバケットにあってもかまいませんが、同じリージョンに存在している必要があります。詳細については、「[MANIFEST](copy-parameters-data-source-s3.md#copy-manifest)」を参照してください。

以下に `customer-fw-manifest` のテキストを示します。

```
{
  "entries": [
    {"url":"s3://<your-bucket-name>/load/customer-fw.tbl-000"},
    {"url":"s3://<your-bucket-name>/load/customer-fw.tbl-001"},
    {"url":"s3://<your-bucket-name>/load/customer-fw.tbl-002"},
    {"url":"s3://<your-bucket-name>/load/customer-fw.tbl-003"},
    {"url":"s3://<your-bucket-name>/load/customer-fw.tbl-004"},    
    {"url":"s3://<your-bucket-name>/load/customer-fw.tbl-005"},
    {"url":"s3://<your-bucket-name>/load/customer-fw.tbl-006"}, 
    {"url":"s3://<your-bucket-name>/load/customer-fw.tbl-007"} 
    ]
}
```

**マニフェストファイルを使用して CUSTOMER テーブルのデータをロードするには**

1. テキストエディタで `customer-fw-manifest` ファイルを開きます。

1. *<your-bucket-name>* の部分はお客様のバケットの名前に置き換えます。

1. ファイルを保存します。

1. バケットのロードフォルダにファイルをアップロードします。

1. 以下の COPY コマンドを実行します。

   ```
   copy customer from 's3://<your-bucket-name>/load/customer-fw-manifest'
   credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>' 
   fixedwidth 'c_custkey:10, c_name:25, c_address:25, c_city:10, c_nation:15, c_region :12, c_phone:15,c_mktsegment:10'
   maxerror 10 
   acceptinvchars as '^'
   manifest;
   ```

#### DATEFORMAT を使用した DWDATE テーブルのロード
<a name="tutorial-loading-load-dwdate"></a>

このステップでは、DELIMITER オプションと DATEFORMAT オプションを使用して、DWDATE テーブルをロードします。

DATE 列と TIMESTAMP 列をロードする場合、COPY ではデフォルトの形式を想定しています。日付の場合は YYYY-MM-DD で、タイムスタンプの場合は YYYY-MM-DD HH:MI:SS です。ロードデータでデフォルトの形式が使用されていない場合、DATEFORMAT と TIMEFORMAT を使用して形式を指定できます。

次の例は、DWDATE テーブルの日付形式を示しています。列 2 の日付形式が一貫していないことに注意してください。

```
19920104	1992-01-04          Sunday		January	1992	199201	Jan1992	1	4	4	1...
19920112	January 12, 1992	Monday		January	1992	199201	Jan1992	2	12	12	1...
19920120	January 20, 1992	Tuesday	    January	1992	199201	Jan1992	3	20	20	1...
```
<a name="tutorial-loading-dateformat"></a>
**DATEFORMAT**  
日付形式は 1 つだけ指定できます。ロードデータに一貫性のない形式が含まれている場合やその形式が異なる列に含まれている場合、または形式がロード時にわからない場合は、DATEFORMAT を `'auto'` 引数と共に使用します。`'auto'` を指定すると、COPY は有効な日付または時間形式を認識してデフォルト形式に変換します。`'auto'` オプションは、DATEFORMAT および TIMEFORMAT 文字列を使用する場合にサポートされない形式を認識します。詳細については、「[DATEFORMAT と TIMEFORMAT で自動認識を使用する](automatic-recognition.md)」を参照してください。

DWDATE テーブルをロードするには、以下の COPY コマンドを実行します。

```
copy dwdate from 's3://<your-bucket-name>/load/dwdate-tab.tbl'
credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>' 
delimiter '\t' 
dateformat 'auto';
```

#### 複数のデータファイルをロードする
<a name="tutorial-loading-load-lineorder"></a>

GZIP オプションと COMPUPDATE オプションを使用してテーブルをロードできます。

1 つのデータファイルまたは複数のファイルからテーブルをロードできます。実際に試して、2 つの方法のロード時間を比較しましょう。
<a name="tutorial-loading-gzip-lzop"></a>
**GZIP、LZOP および BZIP2**  
ファイルは gzip、lzop、または bzip2 圧縮形式を使って圧縮できます。圧縮ファイルからロードする場合、COPY はロードの過程でファイルを解凍します。ファイルを圧縮すると、ストレージ領域を節約し、アップロード時間を短縮できます。
<a name="tutorial-loading-compupdate"></a>
**COMPUPDATE**  
COPY は、圧縮エンコードなしで空のテーブルをロードする場合、ロードデータを分析し、最適なエンコードを決定します。次に、ロードを開始する前にそのエンコードを使用するようにテーブルを変更します。この分析プロセスは時間がかかりますが、分析が行われるのはテーブルごとに多くて 1 回です。時間を節約するには、COMPUPDATE をオフにすることにより、このステップを省略できます。COPY の実行時間を正確に評価するために、このステップでは COMPUPDATE をオフにします。
<a name="tutorial-loading-multiple-files"></a>
**複数のファイル**  
COPY コマンドでは、1 つのファイルからロードする代わりに、複数のファイルから並列でロードすると、データを非常に効率的にロードできます。ファイルの数がクラスターのスライスの数の倍数になるようにデータをファイルに分割します。そうすることで Amazon Redshift はワークロードを分割し、スライス間で均等にデータを配分します。ノードあたりのスライスの数は、クラスターのノードサイズによって決まります。各ノードサイズに含まれるスライスの数の詳細については、「*Amazon Redshift 管理ガイド*」の「[クラスターおよびノードについて](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-about-clusters-and-nodes)」を参照してください。

例えば、このチュートリアルで使用するクラスターのコンピューティングノードにはスライスが 2 個ずつあるため、4 ノードのクラスターの場合、スライスは 8 個です。前の手順では、ロードデータが非常に小さい 8 つのファイルに格納されていました。1 つの大きいファイルからロードする場合と複数のファイルからロードする場合について、時間の差を比較できます。

レコード数が 1,500 万、容量が約 1.2 GB のファイルでさえ、Amazon Redshift のスケールでは極小です。とは言え、複数のファイルからロードした場合のパフォーマンス上の利点を示すには十分です。

次の画像は、LINEORDER のデータファイルを示しています。

![\[9 つのファイルに分割された LINEORDER テーブルのデータ。\]](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/images/tutorial-load-lineorder-files.png)


**複数のファイルを使用して COPY のパフォーマンスを評価するには**

1. ラボのテストでは、次のコマンドを実行して、単一のファイルからコピー (COPY) しました。このコマンドは架空のバケットを示しています。

   ```
   copy lineorder from 's3://amzn-s3-demo-bucket/load/lo/lineorder-single.tbl' 
   credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>' 
   gzip
   compupdate off
   region 'us-east-1';
   ```

1. 結果は次のとおりでした。実行時間を書き留めてください。

   ```
   Warnings:
   Load into table 'lineorder' completed, 14996734 record(s) loaded successfully.
   
   0 row(s) affected.
   copy executed successfully
   
   Execution time: 51.56s
   ```

1. 次に、次のコマンドを実行して、複数のファイルからコピー (COPY) しました。

   ```
   copy lineorder from 's3://amzn-s3-demo-bucket/load/lo/lineorder-multi.tbl' 
   credentials 'aws_iam_role=arn:aws:iam::<aws-account-id>:role/<role-name>' 
   gzip
   compupdate off
   region 'us-east-1';
   ```

1. 結果は次のとおりでした。実行時間を書き留めてください。

   ```
   Warnings:
   Load into table 'lineorder' completed, 14996734 record(s) loaded successfully.
   
   0 row(s) affected.
   copy executed successfully
   
   Execution time: 17.7s
   ```

1. 実行時間を比較します。

   この実験では、1,500 万件のレコードのロード時間が 51.56 秒から 17.7 秒に短縮されました。65.7% の削減です。

   これらの結果は 4 ノードクラスターの使用に基づいています。クラスターにさらにノードがある場合は、時間の節約は増加します。数十個から数百個のノードがある、一般的な Amazon Redshift クラスターの場合、違いはさらに明確になります。単一ノードクラスターの場合、実行時間の差はほとんどありません。

## ステップ 6: データベースにバキューム操作を実行し、分析する
<a name="tutorial-loading-data-vacuum"></a>

相当数の行を追加、削除、変更するたびに、VACUUM コマンドを実行してから ANALYZE コマンドを実行する必要があります。*バキューム*操作によって、削除された行から領域を回復し、ソート順序を復元します。ANALYZE コマンドは統計メタデータを更新し、クエリオプティマイザがさらに正確なクエリプランを生成できるようにします。詳細については、「[テーブルのバキューム処理](t_Reclaiming_storage_space202.md)」を参照してください。

ソートキー順序でデータをロードする場合、バキューム処理は高速です。このチュートリアルでは、かなりの行数を追加しましたが、空のテーブルに追加しました。このような場合、再ソートは必要ではなく、行を削除していません。COPY は空のテーブルをロードした後に自動的に統計を更新するため、統計は最新の状態になっているはずです。ただし、適切なハウスキーピングを行うため、データベースにバキューム処理を実行し、分析することで、このチュートリアルを完了します。

データベースをバキュームして分析するには、以下のコマンドを実行します。

```
vacuum;
analyze;
```

## ステップ 7: リソースをクリーンアップする
<a name="tutorial-loading-data-clean-up"></a>

クラスターが実行されている限り料金が発生し続けます。このチュートリアルの完了後は、*Amazon Redshift 入門ガイド*の「[ステップ 5: アクセスを取り消してサンプルクラスターを削除する](https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-clean-up-tasks.html)」の手順に従って、環境を以前の状態に戻す必要があります。

クラスターを維持するが、SSB テーブルで使用されるストレージを復元したいという場合は、以下のコマンドを実行します。

```
drop table part;
drop table supplier;
drop table customer;
drop table dwdate;
drop table lineorder;
```

### 次
<a name="tutorial-loading-next-summary"></a>

[概要](#tutorial-loading-data-summary)

## 概要
<a name="tutorial-loading-data-summary"></a>

このチュートリアルでは、データファイルを Amazon S3 にアップロードした後、COPY コマンドを使用してデータをファイルから Amazon Redshift テーブルにロードしました。

次の形式を使用してデータをロードしました。
+ 文字区切り
+ CSV
+ 固定幅

STL\$1LOAD\$1ERRORS システムテーブルを使用してロードエラーをトラブルシューティングし、次に REGION、MANIFEST、MAXERROR、ACCEPTINVCHARS、DATEFORMAT、および NULL AS オプションを使用してエラーを修正しました。

データのロードに関する以下のベストプラクティスを適用しました。
+ [COPY コマンドを使用したデータのロード](c_best-practices-use-copy.md)
+ [データファイルをロードする](c_best-practices-use-multiple-files.md)
+ [単一の COPY コマンドを使用した複数のファイルからのロード](c_best-practices-single-copy-command.md)
+ [データファイルを圧縮する](c_best-practices-compress-data-files.md)
+ [ロードの前後におけるデータファイルの検証](c_best-practices-verifying-data-files.md)

Amazon Redshift のベストプラクティスの詳細については、次のリンクを参照してください。
+ [データをロードするための Amazon Redshift のベストプラクティス](c_loading-data-best-practices.md)
+ [Amazon Redshift テーブル設計のベストプラクティス](c_designing-tables-best-practices.md) 
+ [Amazon Redshift クエリの設計のベストプラクティス](c_designing-queries-best-practices.md) 