

 Amazon Redshift 將不再支援從修補程式 198 開始建立新的 Python UDFs。現有 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 資料庫中。載入資料的常用來源之一，就是 Amazon S3 檔案。下表摘要說明從 Amazon S3 來源開始搭配使用的一些方法。


| 使用的方法 | Description | 需要方法時 | 
| --- | --- | --- | 
| COPY command (COPY 命令) | 執行批次檔案擷取，以從 Amazon S3 檔案載入資料。此方法利用 Amazon Redshift 的平行處理功能。如需詳細資訊，請參閱[使用 COPY 命令載入資料表](t_Loading_tables_with_the_COPY_command.md)。 | 當需要手動初始化批次檔案擷取的基本資料載入需求時，應使用此方法。此方法大多用於自訂和第三方檔案擷取管道，或一次性或臨機操作的檔案擷取工作負載。 | 
| 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/zh_tw/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)。 | 應在您需要快速從本機電腦載入檔案以進行一次性查詢時使用。透過此方法，Amazon Redshift 查詢編輯器 v2 會將檔案暫時儲存在客戶擁有的 Amazon S3 儲存貯體上，並使用此 Amazon S3 路徑執行複製命令。 | 

COPY 命令是載入資料表的最有效方式。您也可以使用 INSERT 命令將資料新增至您的資料表，但與使用 COPY 相較，此方式效率明顯較低。COPY 命令能夠同時從多個資料檔案或多個資料串流中進行讀取。Amazon Redshift 會將工作負載配置到 Amazon Redshift 節點並平行執行載入操作，包括排序資料列以及將資料分配到各節點切片。

**注意**  
Amazon Redshift Spectrum 外部資料表處於唯讀狀態。您無法 COPY 或 INSERT 至外部資料表。

若要存取其他 AWS 資源上的資料，Amazon Redshift 必須具有存取這些資源的許可，並執行存取資料所需的動作。您可以使用 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 入門指南》**示範了簡單的 COPY 命令用法，以使用預設 IAM 角色載入 Amazon S3 資料。請參閱[步驟 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)。

若要從其他 AWS 資源載入資料，Amazon Redshift 必須具有存取資源和執行必要動作的許可。

若要授予或撤銷使用 COPY 命令將資料載入至資料表的權限，請授予或撤銷 INSERT 權限。

您的資料必須採用適當的格式，才能載入至您的 Amazon Redshift 資料表。本節說明用於在載入您的資料之前準備和驗證資料，以及執行之前用於驗證 COPY 陳述式的準則。

若要保護您的檔案中的資訊，您可以先將資料檔案加密再將其上傳至您的 Amazon S3 儲存貯體；COPY 會在執行載入時解密資料。您也可以對使用者提供暫時的安全性登入資料，來限制對您的載入資料的存取。暫時安全性登入資料提供加強的安全性，因為有效期限較短，且過期之後不能重複使用。

Amazon Redshift 具有內建的 COPY 功能，可快速載入未壓縮的已分隔資料。但您可以使用 gzip、lzop 或 bzip2 壓縮檔案來節省上傳檔案的時間。

如果 COPY 查詢中有下列關鍵字，則不支援自動分割未壓縮的資料：ESCAPE、REMOVEQUOTES 和 FIXEDWIDTH。但是支援 CSV 關鍵字。

Amazon Redshift AWS 會使用硬體加速 SSL 與 Amazon S3 或 Amazon DynamoDB 通訊，以進行 COPY、UNLOAD、備份和還原操作，以協助確保資料傳輸的安全。

直接從 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 必須經過身分驗證，才能獲得授權來存取資源。您可以選擇角色型存取控制或金鑰型存取控制中的一個。本節說明這兩個方法的概觀。如需詳細資訊和範例，請參閱[存取其他 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 管理指南》中的建立 IAM 角色以允許 Amazon Redshift 叢集存取 AWS 服務](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 Resource Name (ARN)。若要使用 IAM 角色來執行 COPY 命令，請使用 IAM\$1ROLE 參數或 CREDENTIALS 參數來提供角色 ARN。

下列 COPY 命令範例會使用 IAM\$1ROLE 參數搭配角色 `MyRedshiftRole` 進行身分驗證。

```
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 和私密存取金鑰。 

**注意**  
強烈建議使用 IAM 角色來驗證身分，而不要提供純文字存取金鑰 ID 和私密存取金鑰。如果您選擇以金鑰為基礎的存取控制，則絕不要使用 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 命令將會失敗。

使用下列準則來幫助確保您的輸入資料有效：
+ 您的資料只可以包含長度最多四個位元組的 UTF-8 字元。
+ 驗證 CHAR 和 VARCHAR 字串的長度未多於對應資料欄的長度。VARCHAR 字串是以位元組而非字元測量，因此，以中文字元四字元字串而言，每個會佔用四個位元組，所以需要 VARCHAR(16) 資料欄。
+ 多位元組字元只可以搭配 VARCHAR 資料欄使用。驗證多位元組字元長度不超過四個位元組。
+ 驗證 CHAR 資料欄的資料僅包含單位元組字元。
+ 請勿包含任何特殊字元或語法來指出記錄中的最後一個欄位。此欄位可以是分隔符號。
+ 如果您的資料包含 null 結束字元，也稱為 NUL (UTF-8 0000) 或二進位零 (0x000)，您可以藉由在 COPY 命令中使用 NULL AS 選項，以 NULLS 的形式將這些字元載入至 CHAR 或 VARCHAR 資料欄：`null as '\0'` 或 `null as '\000'`。如果您不使用 NULL AS，null 結束字元將造成您的 COPY 失敗。
+ 如果您的字串包含特殊字元，例如分隔符號和內嵌的換行字元，請使用 ESCAPE 選項搭配 [COPY](r_COPY.md) 命令。
+ 驗證所有單引號和雙引號均正確成對。
+ 驗證浮點字串採用標準浮點格式，例如 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)。依預設，所有資料表資料欄已載入，但您可以選擇性地定義以逗點分隔的資料欄清單。如果資料表資料欄未包含在 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>

載入壓縮的資料時，建議您將每個資料表的資料分割為多個檔案。載入未壓縮的已分隔資料後，COPY 命令會使用大量平行處理 (MPP) 和掃描範圍，從 Amazon S3 儲存貯體中的大型檔案載入資料。

## 從多個壓縮的檔案載入資料
<a name="t_splitting-data-files-compressed"></a>

如果您有壓縮的資料，建議您將每個資料表的資料分割為多個檔案。COPY 命令可以從多個檔案平行載入資料。您可以透過為集合指定通用字首或*字首索引鍵*，或在資訊清單檔案中明確列出檔案來載入多個檔案。

將您的資料分割為檔案，使得檔案的數量為您的叢集中配量數量的倍數。以該方式，Amazon Redshift 可以在配量間平均分割資料。每一節點的配量數目取決於叢集的節點大小。例如，每個 dc2.large 運算節點有兩個切片，而每個 dc2.8xlarge 運算節點有 16 個切片。如需每個節點大小有多少配量的相關資訊，請參閱《Amazon Redshift 管理指南》**中的[關於叢集和節點](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-about-clusters-and-nodes)。

節點全部會參與在執行的平行查詢中，以處理盡可能平均地分佈於配量的資料。如果您的叢集包含兩個 dc2.large 節點，您可以將資料分割成四 (或四的倍數) 個檔案。Amazon Redshift 在分割工作負載時，不會考量檔案大小。因此，您需要確定壓縮後的檔案大小大致相同 (從 1 MB 到 1 GB)。

若要使用物件字首來識別載入檔案，將每個檔案以通用字首命名。例如，`venue.txt` 檔案可以分割為四個檔案，如下所示。

```
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 儲存貯體中的大型檔案中載入資料範圍。檔案必須已分隔，才能進行平行載入。例如，以縱線字元分隔。使用 COPY 命令自動進行平行資料載入也可用於 CSV 檔案。您可以藉由在資料表上設定分佈索引鍵來利用平行處理。如需分佈索引鍵的相關資訊，請參閱[分配資料以實現查詢最佳化](t_Distributing_data.md)。

若 COPY 查詢包含下列任何關鍵字，則不支援自動平行資料載入：ESCAPE、REMOVEQUOTES 和 FIXEDWIDTH。

來自檔案的資料會載入到目標資料表，每個資料列一行。資料檔案中的欄位會依次與資料表資料欄對應，由左至右。資料檔案中的欄位可以是固定寬度或以字元分隔；預設的分隔符號為管線 (\$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)。

**重要**  
必須在與您叢集所在的相同 ‏ AWS 區域中建立存放資料檔案的 Amazon S3 儲存貯體，除非您使用 [REGION](copy-parameters-data-source-s3.md#copy-region) 選項來指定 Amazon S3 儲存貯體所在的區域。

確定 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 EXTERNAL TABLE AS 和 Amazon S3 Redshift Spectrum 操作提供強大的read-after-write一致性。此外，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)來遵循所述步驟，並搭配您使用的其他要求：
+ **對稱加密 –** 適用於 Java 的 AWS 開發套件 `AmazonS3EncryptionClient` 類別使用上述基於對稱金鑰加密的封套加密程序。使用此類別來建立 Amazon S3 用戶端，以上傳用戶端加密的資料。
+ **256 位元 AES 根對稱金鑰 –** 根金鑰會加密信封金鑰。您可以將根金鑰傳遞至您的 `AmazonS3EncryptionClient` 類別執行個體。儲存此金鑰，因為您將需要用它將資料複製到 Amazon Redshift。
+ **用來儲存加密信封金鑰的物件中繼資料 –** 依預設，Amazon S3 會將信封金鑰儲存為 `AmazonS3EncryptionClient` 類別的物件中繼資料。儲存為物件中繼資料的加密信封金鑰會在解密程序期間使用。

**注意**  
若您在初次使用加密 API 時得到密碼套件加密錯誤訊息，您的 JDK 版本可能包含將加密及解密轉換之金鑰長度上限限制為 128 位元的 Java Cryptography Extension (JCE) 管轄權政策檔案。如需有關解決此問題的資訊，請參閱《*Amazon Simple Storage Service 使用者指南*》中的[使用適用於 Java 的 AWS SDK 指定用戶端加密](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>

如需如何使用適用於 Java 的 AWS SDK 上傳用戶端加密資料的範例，請參閱《*Amazon Simple Storage Service 使用者指南*》中的[使用用戶端加密保護資料](https://docs.aws.amazon.com/AmazonS3/latest/userguide/encrypt-client-side-symmetric-master-key.html)。

第二個選項會顯示在用戶端加密期間要讓資料可以在 Amazon Redshift 中載入，您必須進行的選擇。具體來說，此範例會顯示使用物件中繼資料來儲存加密的信封金鑰和使用 256 位元 AES 根對稱金鑰。

此範例提供使用適用於 Java 的 AWS 開發套件建立 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 Resource Name (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)

如果想要驗證您的資料而不實際載入資料表，請使用 NOLOAD 選項搭配 [COPY](r_COPY.md) 命令。

下列範例顯示名為 `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` 檔案可以分割為四個檔案，如下所示：

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

下列 COPY 命令會使用資料檔案中以管線分隔的資料來載入 VENUE 資料表，具有 Amazon S3 儲存貯體 `amzn-s3-demo-bucket` 中的字首 '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) COPY 範例。

下列範例顯示的 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`。不考慮任何必要設定，只要找不到檔案，COPY 就會終止。

下列範例會執行 COPY 命令並搭配上一個範例中的資訊清單，名為 `cust.manifest`。

```
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>

[UNLOAD](r_UNLOAD.md) 操作使用 MANIFEST 參數建立的資訊清單可能會有 COPY 操作不需要的索引鍵。例如，以下 `UNLOAD` 清單檔案包含 `meta` 索引鍵，針對 Amazon Redshift Spectrum 外部資料表，還有載入 `ORC` 或 `Parquet` 檔案格式的資料檔案時，都需要此索引鍵。`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* 參數是字串，包含每個資料欄的識別碼以及每個資料欄的寬度，以冒號分隔。**column:width** 對組是使用逗號分隔。識別碼可以是您選擇的任何項目：數字、字母或兩者的結合。識別碼對資料表本身沒有關聯，所有規格必須以與資料表相同的順序包含資料欄。

下列兩個範例會顯示相同的規格，第一個使用數值識別碼，而第二個使用字串識別碼：

```
'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 資料類型支援四位元組 UTF-8 字元，但 CHAR 資料類型只接受單位元組 ASCII 字元。您無法將五位元組或更長的字元載入 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 命令從 Amazon EMR 叢集平行載入資料，而叢集設定為以固定寬度檔案、字元分隔檔案、CSV 檔案或 JSON 格式檔案的形式，將文字檔案寫入叢集的 Hadoop 分散式檔案系統 (HDFS)。

## 從 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 分散式檔案系統 (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 Redshift 叢集公有金鑰新增至每個 Amazon EC2 主機的授權金鑰檔案](#load-from-emr-steps-add-key-to-host)** 

  您可以將 Amazon Redshift 叢集公有金鑰新增至主機的授權金鑰檔案，以便主機識別 Amazon Redshift 叢集並接受 SSH 連線。
+ **[步驟 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 分散式檔案系統 (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. 針對 Amazon EMR 叢集組態中的**自動終止**選項指定**否**，以便叢集在 COPY 命令執行時保持可用狀態。
**重要**  
如果 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. 在導覽窗格中，選擇**叢集**連結。

1. 從清單選取您的叢集。

1. 找到 **SSH Ingestion Settings (SSH 擷取設定)** 群組。

   記下 **Cluster Public Key (叢集公有金鑰)** 和 **Node IP addresses (節點 IP 地址)**。您將在稍後的步驟中用到它們。  
![\[SSH 擷取設定群組的螢幕擷取畫面，其中顯示叢集公有金鑰和節點 IP 位址。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/copy-from-ssh-console-2.png)

   您將使用步驟 3 的私有 IP 地址來設定 Amazon EC2 主機以接受來自 Amazon Redshift 的連線。

若要使用 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 Redshift 叢集公有金鑰新增至每個 Amazon EC2 主機的授權金鑰檔案
<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 叢集節點新增一個輸出規則。針對**類別**，對連接埠 22 上的 TCP 通訊協定選取 SSH。針對**來源**，輸入您在 [步驟 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 執行個體或其他電腦。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>

開始之前，您應該備妥下列各項：
+ 您可以使用 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/](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 叢集公有金鑰新增至主機的授權金鑰檔案，以便主機識別 Amazon Redshift 叢集並接受 SSH 連線。
+ **[步驟 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)** 

  清單檔案是 JSON 格式的文字檔案，具有 Amazon Redshift 連線至主機和擷取資料所需的詳細資訊。
+ **[步驟 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. 在導覽窗格中，選擇**叢集**連結。

1. 從清單選取您的叢集。

1. 找到 **SSH Ingestion Settings (SSH 擷取設定)** 群組。

   記下 **Cluster Public Key (叢集公有金鑰)** 和 **Node IP addresses (節點 IP 地址)**。您將在稍後的步驟中用到它們。  
![\[SSH 擷取設定群組的螢幕擷取畫面，其中顯示叢集公有金鑰和節點 IP 位址。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/copy-from-ssh-console-2.png)

   您將使用步驟 3 的 IP 地址來設定主機以接受來自 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。針對**來源**，輸入您在 [步驟 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 命令不需要主機公有金鑰，但因為安全原因，我們強烈建議使用公有金鑰來幫助避免 'man-in--middle' 攻擊。

您可以在下列位置中尋找主機的公有金鑰，其中的 `<ssh_host_rsa_key_name>` 為主機公有金鑰的唯一名稱：

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

**注意**  
Amazon Redshift 只支援 RSA 金鑰。我們不支援 DSA 索引鍵。

在步驟 5 建立您的資訊清單檔案時，您會將公有金鑰的文字貼上至資訊清單檔案項目中的「公有金鑰」資料欄。

## 步驟 5：建立資訊清單檔案
<a name="load-from-host-steps-create-manifest"></a>

COPY 命令可以使用 SSH 來連接至多台主機，也可以對每台主機建立多個 SSH 連線。COPY 會透過每個主機連線執行命令，然後將命令的輸出平行載入資料表。資訊清單檔案是 JSON 格式的文字檔案，供 Amazon Redshift 用來連接至主機。資訊清單檔案指定 SSH 主機端點，以及在主機上執行以將資料傳回給 Amazon Redshift 的命令。您可以選擇在每個項目中包含主機公有金鑰、登入使用者名稱及 mandatory 旗標。

在本機電腦上建立資訊清單檔案。在稍後的步驟中，您會將檔案上傳到 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 連線包含一個 "entries" 結構。每個項目代表單一 SSH 連線。您可以對單一主機建立多個連線，也可以對多台主機建立多個連線。如上所示，欄位名稱和值都需要雙引號。不需要雙引號的唯一值為強制欄位的布林值 **true** 或 **false**。

下列描述資訊清單檔案中的欄位。

端點  
主機的 URL 地址或 IP 地址。例如，"`ec2-111-222-333.compute-1.amazonaws.com`" 或 "`22.33.44.56`"

command   
主機將執行的命令，以產生文字或二進位 (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`，請在公有金鑰欄位中輸入下列文字：`AbcCbaxxx…xxxDHKJ`。

mandatory  
(選用) 指出如果嘗試連線失敗，COPY 命令是否就應該失敗。預設值為 `false`。如果 Amazon Redshift 未成功建立至少一個連線，則 COPY 命令會失敗。

使用者名稱  
(選用) 用來登入主機系統並執行遠端命令的使用者名稱。使用者登入名稱與步驟 2 中用來將公有金鑰新增至主機授權金鑰檔案的登入必須相同。預設的使用者名稱為 "redshift"。

下列範例顯示完整的清單檔案，可開啟對相同主機的四個連線，並透過每個連線執行不同的命令：

```
{ 
  "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/](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 命令會執行兩次資料讀取，也就是會執行遠端命令兩次。第一次讀取會提供樣本進行壓縮分析，第二次讀取就實際載入資料。如果執行遠端命令兩次可能因為潛在的副作用造成問題，您應該關閉自動壓縮。若要關閉自動壓縮，請在執行 COPY 命令時將 COMPUPDATE 選項設為 OFF。如需詳細資訊，請參閱[利用自動壓縮載入資料表](c_Loading_tables_auto_compress.md)。

# 從 Amazon DynamoDB 資料表載入資料
<a name="t_Loading-data-from-dynamodb"></a>

您可以使用 COPY 命令，從單一 Amazon DynamoDB 資料表載入具有資料的資料表。

**重要**  
除非您使用 [REGION](copy-parameters-data-source-s3.md#copy-region)選項來指定 Amazon DynamoDB 資料表所在的 AWS 區域，否則必須在與叢集相同的 AWS 區域中建立提供資料的 Amazon DynamoDB 資料表。

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 命令將會失敗。
+ 取決於在 [COPY](r_COPY.md) 命令中搭配 EMPTYASNULL 選項指定的值，不符合 Amazon DynamoDB 資料表中屬性的 Amazon Redshift 資料表資料欄會以 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>';
```

*授權*的值是存取 Amazon DynamoDB 資料表所需的 AWS 登入資料。如果這些登入資料對應於某個使用者，該使用者必須具備許可能夠 SCAN 和 DESCRIBE 要載入的 Amazon DynamoDB 資料表。

*授權*值提供叢集存取 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 Resource Name (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)

如果想要驗證您的資料而不實際載入資料表，請使用 NOLOAD 選項搭配 [COPY](r_COPY.md) 命令。

下列範例會從 DynamoDB 資料表 my-favorite-movies-table 載入具有資料的 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 個資料列。

取樣之後，會捨棄樣本資料列並載入整個資料表。因此，許多資料列會讀取兩次。如需自動壓縮運作方式的相關資訊，請參閱[利用自動壓縮載入資料表](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 資料類型支援四位元組 UTF-8 字元，但 CHAR 資料類型只接受單位元組 ASCII 字元。您無法將五位元組或更長的字元載入 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 資料表中的資料，在實際載入資料之前，請使用 NOLOAD 選項搭配 [COPY](r_COPY.md) 命令。使用 NOLOAD 搭配用來載入資料的相同 COPY 命令和選項。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>

您可以根據自己對資料的評估，將壓縮編碼手動套用至資料表中的資料欄。或者，您可以使用 COPY 命令，搭配使用設為 ON 的 COMPUPDATE，根據範例資料自動分析並套用壓縮。

您可以在建立和載入全新資料表時使用自動壓縮。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 命令，且所有資料表資料欄都是 RAW 編碼或無編碼時，COPY 命令會套用自動壓縮。

若要對空白資料表套用自動壓縮，而不論其目前的壓縮編碼，請在執行 COPY 命令時將 COMPUPDATE 選項設為 ON。若要關閉自動壓縮，請在執行 COPY 命令時將 COMPUPDATE 選項設為 OFF。

您不可以套用自動壓縮至已包含資料的資料表。

**注意**  
自動壓縮分析需要在載入資料中有足夠的資料列 (每個配量至少 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 資料庫包含 LISTING 資料表的複本 (名為 BIGLIST)，而您想要在載入大約 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>

如果您的資料表有非常少的資料欄但有非常大量的資料列，三個隱藏的中繼資料身分資料欄 (INSERT\$1XID、DELETE\$1XID、ROW\$1ID) 將耗用資料表不成比例的磁碟空間量。

 為了最佳化隱藏資料欄的壓縮，若可能，請在單一 COPY 交易中載入資料表。如果您使用多個不同的 COPY 命令來載入資料表，INSERT\$1XID 資料欄將不會壓縮良好。如果您使用多個 COPY 命令，將必須執行清空操作，但它不會改善 INSERT\$1XID 的壓縮。

# 載入預設的欄位值
<a name="c_loading_default_values"></a>

您可以選擇性地在您的 COPY 命令中定義資料欄清單。如果已從資料欄清單忽略資料表中的資料欄，COPY 將使用 DEFAULT 選項提供的值 (在 CREATE TABLE 命令中指定)，或如果未指定 DEFAULT 選項，則使用 NULL 來載入資料欄。

如果 COPY 嘗試將 NULL 指派給定義為 NOT NULL 的欄，COPY 命令會失敗。如需指派 DEFAULT 選項的詳細資訊，請參閱[CREATE TABLE](r_CREATE_TABLE_NEW.md)。

從 Amazon S3 上的資料檔案載入時，資料欄清單中的資料欄必須採用與資料檔案中的欄位相同的順序。如果資料檔案中的欄位在資料欄清單中沒有對應的資料欄，COPY 命令失敗。

從 Amazon DynamoDB 資料表載入時，順序並不重要。Amazon DynamoDB 屬性中不符合 Amazon Redshift 資料表中資料欄的所有欄位則會遭捨棄。

下列限制適用於使用 COPY 命令載入 DEFAULT 值至資料表時：
+ 如果 [IDENTITY](r_CREATE_TABLE_NEW.md#identity-clause) 資料欄包括在資料欄清單中，也必須在 [COPY](r_COPY.md) 命令中指定 EXPLICIT\$1IDS 選項，否則 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 Redshift 的 Amazon S3 事件整合和 COPY JOB 常見問題進行故障診斷。

## 建立 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)。

或者，您可以使用 [REGION](copy-parameters-data-source-s3.md#copy-region) 選項搭配 COPY 命令來指定區域。

## 存取遭拒
<a name="s3-access-denied-error"></a>

如果使用者沒有足夠的許可，您會收到下列錯誤訊息：

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

其中一個可能的原因是憑證所識別的使用者沒有 Amazon S3 儲存貯體的 LIST 和 GET 存取權。如需其他原因的資訊，請參閱《Amazon S imple Storage Service 使用者指南》**中的[針對 Amazon S3 中的拒絕存取 (403 禁止) 錯誤進行疑難排解](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，或 7F hex，它也是 ASCII 字元集。VARCHAR 資料欄接受多位元組 UTF-8 字元，最長四個位元組。如需詳細資訊，請參閱[字元類型](r_Character_types.md)。

如果您的載入資料中的資料行包含對資料欄資料類型無效的字元，COPY 會傳回錯誤並將資料列記錄在 STL\$1LOAD\$1ERRORS 系統日誌資料表，錯誤碼 1220。ERR\$1REASON 欄位包括無效字元的位元組序列 (十六進位)。

修正您的載入資料中無效字元的一個替代方式是在載入程序期間取代無效的字元。若要取代無效的 UTF-8 字元，請指定 ACCEPTINVCHARS 選項搭配 COPY 命令。如果設定了 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 十六進位序列。下列範例顯示 COPY 嘗試將 UTF-8 `a4` 載入 VARCHAR 欄位時的錯誤原因。

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

下表列出 VARCHAR 載入錯誤的描述和建議的解決方法。如果發生這些錯誤中的一個，請以有效的 UTF-8 程式碼序列取代該字元或移除該字元。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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/zh_tw/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 會偵測新的 Amazon S3 檔案何時新增至 COPY 命令中指定的路徑。然後，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 政策。此政策必須同時允許針對儲存貯體資源的 `s3:GetObject` (例如 `amzn-s3-demo-bucket`) 和針對儲存貯體資源及其內容的 `s3:ListBucket` (例如 `amzn-s3-demo-bucket/*`)。

------
#### [ 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 會提供**為我修正**選項，以便將此政策新增至您的 Amazon Redshift 資料倉儲。若要自行更新資源政策，您可以使用 [put-resource-policy](https://docs.aws.amazon.com/cli/latest/reference/redshift/put-resource-policy.html) AWS CLI 命令。例如，若要將資源政策連接至 Amazon Redshift 佈建叢集，以便與 Amazon S3 儲存貯體進行 S3 事件整合，請執行類似以下的 AWS CLI 命令。 Amazon S3 下列範例顯示 *us-east-1* AWS 區域 for 使用者帳戶 *123456789012* 中佈建叢集命名空間的政策。儲存貯體名為 *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
  				}
  			}
  		}
  	]
  }
  ```

------

  若要將資源政策連接至 Redshift Serverless 命名空間，以便與 Amazon S3 儲存貯體進行 S3 事件整合，請執行類似以下的 AWS CLI 命令。 Amazon S3 下列範例顯示 *us-east-1* AWS 區域 for 使用者帳戶 *123456789012* 中無伺服器命名空間的政策。儲存貯體名為 *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 儲存貯**體 – 是目前 中的 Amazon S3 儲存貯體 AWS 區域 ， AWS 帳戶 也是將資料擷取至 Amazon Redshift 的來源。
   + **Amazon Redshift 資料倉儲** - 是從整合接收資料的目標 Amazon Redshift 佈建叢集或 Redshift Serverless 工作群組。

     如果您的目標 Amazon Redshift 位於相同的帳戶中，您就可以選取目標。如果目標位於不同的帳戶中，您可以指定 **Amazon Redshift 資料倉儲 ARN**。目標必須具有包含授權主體和整合來源的資源政策。如果您的目標上沒有正確的資源政策，且您的目標位於相同的帳戶中，您可以選取**為我修正**選項，以便在建立整合程序期間自動套用資源政策。如果您的目標位於不同的 中 AWS 帳戶，您需要在 Amazon Redshift 倉儲上手動套用資源政策。

1. 最多可輸入 50 個標籤**索引鍵**和選用的**值** - 提供有關整合的其他中繼資料。

1. 此時會出現檢閱頁面，您可以在此選擇**建立 S3 事件整合**。

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

若要使用 建立 Amazon S3 事件整合 AWS CLI，請使用 `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 事件整合的屬性。

如需這些命令的詳細資訊，請參閱[《Amazon Redshift CLI 指南》](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 一次。之後的執行會使用相同參數。

若要定義和管理 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>

使用自動複製時，請注意下列事項。
+ 您可以為 AWS 帳戶中的每個叢集或工作群組建立最多 200 個 COPY JOB。
+ 您可以為每個 Amazon Redshift 目標建立最多 50 個 S3 事件整合。
+ 您無法在來源 Amazon S3 儲存貯體的儲存貯體名稱中包含句號 (.) 時，建立 S3 事件整合。
+ 您只能在相同來源和目標之間建立一個 S3 事件整合。也就是說，Amazon S3 儲存貯體與 Amazon Redshift 資料倉儲之間一次只能有一個 S3 事件整合。
+ 您無法在來源 Amazon S3 儲存貯體上定義事件類型 `S3_OBJECT_CREATED` 的任何現有事件通知。不過，在 S3 事件整合建立之後，您可以使用範圍較窄的字首/字尾來更新 Amazon S3 儲存貯體事件通知。如此一來，您也可以設定 `S3_OBJECT_CREATED` 作為其他目標的另一個字首/字尾，並避免與 S3 事件整合發生衝突。如果您遇到自動複製未如預期執行的問題，請在聯絡時為有問題的時間範圍準備 S3 儲存貯體上的`s3:PutBucketNotificationConfiguration`動作 AWS CloudTrail 日誌 AWS 支援。

## 支援的區域
<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 | 
| Europe (Paris) | Available | 
| 以色列 (特拉維夫) | Available | 
| 中東 (阿拉伯聯合大公國) | Available | 
| Middle East (Bahrain) | 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) 會使用名為 TICKIT 資料集的 Amazon Redshift 範例資料集。作為先決條件，您可以依照[開始使用一般資料庫任務](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>

如果您要覆寫目標資料表中的所有資料欄，執行合併最快的方式是取代現有的資料列。這只會掃描目標資料表一次，透過使用內部聯結來刪除將要更新的資料列。刪除資料列之後，這些資料列會透過臨時資料表中的單一插入操作被新資料列取代。

如果下列各項皆成立，請使用此方法：
+ 您的目標資料表和您的臨時資料表包含相同的資料欄。
+ 您想要將目標資料表資料欄中的所有資料取代為所有臨時資料表資料欄。
+ 您將在合併中使用臨時資料表的所有資料列。

如果任一條件不適用，請使用「合併方法 2：指定資料欄清單」，而不是使用 MERGE，如下一節所示。

如果您將不會使用臨時資料表中的所有資料列，請使用 WHERE 子句來篩選 DELETE 和 INSERT 陳述式，將未變更的資料列省略。不過，如果臨時資料表中的多數資料列將不會參與合併，我們建議在個別步驟中執行 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. 建立臨時資料表，然後將它填入要合併的資料，如下列虛擬程式碼所示。

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

1.  您可以使用 MERGE 與臨時資料表執行內部聯結，以更新目標資料表中符合臨時資料表的資料列，然後將所有剩餘的資料列插入與臨時資料表不符的目標資料表中。

    我們建議您在單一 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 TABLE stage;
   ```

# 指定欄位清單但不使用 MERGE 命令，以執行合併操作
<a name="merge-specify-a-column-list"></a>

當您執行程序中詳述的合併操作時，請將所有步驟置於單一交易中。如果有任何步驟失敗，您可以復原交易。使用單一交易也會減少認可的數目，如此可節省時間和資源。

**指定資料欄清單來執行合併操作**

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)。
   + 如果您將不會在合併中使用所有資料列，請新增子句來篩選要變更的資料列。例如，在一或多個資料欄上新增不相等篩選條件，以排除未變更的資料列。
   + 將更新、刪除和插入操作放置在單一交易區塊，如此一來若發生問題，各個項目都將能復原。

    例如：

   ```
   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. 從臨時資料表插入其餘的資料列。在您於步驟二用於 UPDATE 陳述式的 VALUES 子句中使用相同的資料欄清單。

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

1. 捨棄臨時資料表。

   ```
   drop table stage;
   ```

# 合併範例
<a name="merge-examples"></a>

下列範例會執行合併以更新 SALES 資料表。第一個範例使用較簡易的方法，就是從目標資料表刪除，然後從臨時資料表插入所有資料列。第二個範例需要更新目標資料表中的特定資料欄，因此包括額外的更新步驟。

[合併範例](#merge-examples) 會使用名為 TICKIT 資料集的 Amazon Redshift 範例資料集。作為先決條件，您可以依照[開始使用一般資料庫任務](https://docs.aws.amazon.com/redshift/latest/gsg/database-tasks.html)指南中的指示，設定 TICKIT 資料表和資料。有關範例資料集的更多詳細資訊，請參閱[範例資料庫](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html)。

**範例合併資料來源**

本節中的範例需要包括更新和插入的樣本資料來源。針對範例，我們將建立名為 SALES\$1UPDATE 的樣本資料表，其使用來自 SALES 資料表的資料。我們將以代表 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 資料表在 SALES 資料表上執行與 12 月銷售活動新資料的合併操作。此範例會在有更新的 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` 結構描述，則必須授與使用許可。若要檢視並授與使用權限，您必須是下列其中一個角色：
+  超級使用者。
+  可針對深層複製結構描述授與 USES 許可的使用者。

**使用原始資料表 DDL 來執行深層複製**

1. (選用) 執行名為 `v_generate_tbl_ddl` 的指令碼來重新建立資料表 DDL。

1. 使用原始 CREATE TABLE DDL 建立資料表的複本。

1. 使用 INSERT INTO … SELECT 陳述式以來自原始資料表的資料填入該複本。

1. 檢查舊資料表上授與的權限。您可以在 SVV\$1RELATION\$1PRIVILEGES 系統檢視中看到這些許可。

1. 如有必要，請對新資料表授與舊資料表的許可。

1. 針對在原始資料表中具有權限的每個群組和使用者授與使用許可。如果您的深層複製資料表位於 `public` 結構描述中，或與原始資料表位於相同的結構描述中，則不需要執行此步驟。

1. 捨棄原始資料表。

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. 捨棄目前的資料表。

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. 捨棄暫時資料表。

下列範例會透過建立暫存資料表和截斷原始資料表，在 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。將 STATUPDATE 設為 ON 時，只有資料表擁有者或超級使用者可以執行 ANALYZE 命令或執行 COPY 命令。

Amazon Redshift 也會分析您使用下列命令建立的新資料表：
+ CREATE TABLE AS (CTAS) 
+ CREATE TEMP TABLE AS 
+ SELECT INTO 

對最初載入資料後未分析的新資料表執行查詢時，Amazon Redshift 會傳回警告訊息。在後續更新或載入之後查詢資料表時不會發生警告。如果查詢所參考的資料表尚未分析，當您在該資料表上執行 EXPLAIN 命令時，將會傳回相同的警告訊息。

每當將資料新增至非空白資料表就會大幅改變資料表大小時，您可以明確更新統計資訊。若要這麼做，請執行 ANALYZE 命令，或在 COPY 命令中使用 STATUPDATE ON 選項。若要檢視自前次 ANALYZE 以來插入或刪除的資料列數目的詳細資訊，請查詢 [PG\$1STATISTIC\$1INDICATOR](r_PG_STATISTIC_INDICATOR.md) 系統目錄資料表。

您可以將 [ANALYZE](r_ANALYZE.md) 命令的範圍指定為下列其中一項：
+ 整個目前資料庫
+ 單一資料表
+ 單一資料表中的一或多個特定資料欄
+ 可能用作查詢中述詞的資料欄

 ANALYZE 命令會從資料表取得資料列的樣本，執行一些計算，並儲存所產生的資料欄統計資訊。依預設，Amazon Redshift 會為 DISTKEY 資料欄執行一個樣本階段，以及為資料表中的所有其他資料欄執行另一個樣本階段。如果您想要為資料欄的子集產生統計資料，您可以指定以逗點分隔的資料欄清單。您可以搭配 PREDICATE COLUMNS 子句執行 ANALYZE，以略過未作為述詞的欄。

 ANALYZE 操作相當耗用資源，因此請僅對實際需要統計資料更新的資料表和資料欄執行。您不需要經常或按相同的排程分析所有資料表中的所有資料欄。如果資料本質上變更，請分析在下列項目中經常使用的資料欄：
+ 排序和群組操作
+ 聯結
+ 查詢述詞

為了減少處理時間並提高整體系統效能，對於變更的資料列百分比 (取決於 [analyze\$1threshold\$1percent](r_analyze_threshold_percent.md) 參數) 較低的任何資料表，Amazon Redshift 會略過 ANALYZE。依預設，分析閾值是設為 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 參考僅涵蓋兩年或三年的固定一組日期。在此情況下，這些欄的唯一值不會大幅變更。不過，每個唯一值的執行個體數目將會穩定增加。

此外，考慮相較於 TOTALPRICE 資料欄，較不常查詢 NUMTICKETS 和 PRICEPERTICKET 量值的情況。在此情況下，您可以在每個週末對整個資料表執行一次 ANALYZE 命令，以更新沒有每日分析的五個欄的統計資訊：
<a name="t_Analyzing_tables-predicate-columns"></a>
**述詞欄位**  
做為指定資料欄清單的便利替代方案，您可以選擇僅分析可能用來作為述詞的資料列。執行查詢時，在聯結中使用的任何資料欄、篩選條件或群組依據子句會在系統目錄中標示為述詞資料欄。執行 ANALYZE 搭配 PREDICATE COLUMNS 子句時，分析操作只會包括符合以下條件的資料欄：
+ 此資料欄已標示為述詞資料欄。
+ 資料欄是分佈索引鍵。
+ 資料欄是排序索引鍵的一部分。

如果沒有任一個資料表的資料欄已標示為述詞，ANALYZE 會包括所有資料欄，即使指定了 PREDICATE COLUMNS 亦然。如果沒有資料欄已標示為述詞資料欄，可能是因為尚未查詢該資料表。

當您的工作負載的查詢模式相對穩定時，您可能選擇使用 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。

```
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 的有效資料表權限清單，請參閱 [VACUUM](r_VACUUM_command.md)。  
因此，我們建議視需要清空個別資料表。我們也建議使用此方法，因為清空整個資料庫可能會是相當耗費資源的操作。

## 自動資料表排序
<a name="automatic-table-sort"></a>

Amazon Redshift 會在背景中自動排序資料，以依據其排序索引鍵的順序維護資料表資料。Amazon Redshift 會追蹤您的掃描查詢，以判斷資料表中的哪些區段適合排序。Amazon Redshift 也會追蹤並行擴展叢集的掃描查詢。對於使用 Amazon Redshift 資料共用的多叢集架構，Amazon Redshift 也會追蹤來自資料網格中取用者叢集/工作群組的掃描查詢，包括不同區域的叢集/工作群組。主要叢集、並行擴展叢集和取用者叢集的掃描統計資料會彙總，以判斷資料表的哪些區段將受益於排序。

取決於系統上的載入，Amazon Redshift 會自動啟動排序。這種自動排序能減少執行 VACUUM 命令以將資料保持在排序索引鍵順序的需求。如果您需要資料完全依照排序索引鍵的順序排序 (例如在大型資料載入後)，您仍然可以手動執行 VACUUM 命令。如要判斷您的資料表是否能從執行 VACUUM SORT 中獲益，請監控 [SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md) 中的 `vacuum_sort_benefit` 資料行。

Amazon Redshift 追蹤會掃描每個資料表上使用排序索引鍵的查詢。Amazon Redshift 會估計掃描及篩選每個資料表資料獲得改善的最大百分比 (如果資料表已完全排序的話)。您可以在 [SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md) 中的 `vacuum_sort_benefit` 資料行中看見此估計。您可以使用此資料行搭配 `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 會在兩個階段中執行清空操作：首先，排序未排序區域中的資料列，然後在必要時，將資料表尾端新排序的資料列與現有資料列合併。清空大型資料表時，清空操作會以一系列的步驟進行，其中包含遞增排序，接著是合併。如果操作失敗或如果 Amazon Redshift 在清空期間離線，部分清空的資料表或資料庫將處於一致的狀態，但您將必須手動重新開始清空操作。遞增排序會遺失，但不需要再次清空失敗之前認可的合併資料列。如果未排序的區域很大，損失的時間可能會很可觀。如需排序和合併階段的相關資訊，請參閱[減少合併列的數量](vacuum-managing-vacuum-times.md#vacuum-managing-volume-of-unmerged-rows)。

使用者可以在清空資料表時加以存取。在清空資料表時您可以執行查詢和寫入操作，但是當 DML 和清空並行執行時，這兩項可能都需要較長時間。如果您在清空期間執行 UPDATE 和 DELETE 陳述式，系統效能可能會降低。遞增合併會暫時封鎖並行 UPDATE 和 DELETE 操作，因此 UPDATE 和 DELETE 操作會在受影響的資料表暫時封鎖遞增合併步驟。DDL 操作，例如 ALTER TABLE，會遭到封鎖，直到資料表的清空操作完成為止。

**注意**  
VACUUM 的各種修飾詞都會控制其運作方式。您可以根據當前需求，使用這些修飾詞來制定清空操作。例如，使用 VACUUM RECLUSTER 可透過不執行完整合併操作來縮短清空操作。如需詳細資訊，請參閱[VACUUM](r_VACUUM_command.md)。

## 清空閾值
<a name="vacuum-sort-threshold"></a>

根據預設，若資料表中超過 95% 的資料列已排序，則 VACUUM 會略過資料表的排序階段。略過排序階段可大幅改善 VACUUM 的效能。若要變更單一資料表的預設排序閾值，在執行 VACUUM 命令時，請包含資料表名稱和 TO *閾值* PERCENT 參數。

## 清空類型
<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。重建索引操作相當耗時，因此，若要決定資料表是否將可從重建索引獲益，請查詢 [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 操作載入新資料表，請先執行最大的載入。執行初始載入至新的或截斷的資料表時，所有資料會直接載入至排序的區域，因此不需要清空。
+ 截斷資料表，而非刪除所有資料列。

  從資料表刪除資料列不會回收該資料列佔用的空間，直到您執行清空操作為止；不過，截斷資料表會清空資料表和回收磁碟空間，因此不需要清空。或者，捨棄資料表和重新建立它。
+ 截斷或捨棄測試資料表。

  如果您因測試目的載入少量的資料列至資料表，在完成之前請勿刪除資料列。而是截斷資料表，並在後續生產載入操作中重新載入這些資料列。
+ 執行深層複製。

  如果使用複合排序索引鍵資料表的資料表有大型未排序的區域，深層複製較清空的速度快得多。深層複製會使用會自動重新排序資料表的大量插入來重新建立和重新填入資料表。如果資料表有大型未排序的區域，深層複製較清空的速度快得多。取捨是您不可以在深層複製操作期間進行並行更新，但清空期間卻可以。如需詳細資訊，請參閱[設計查詢的 Amazon Redshift 最佳實務](c_designing-queries-best-practices.md)。

## 減少合併列的數量
<a name="vacuum-managing-volume-of-unmerged-rows"></a>

如果清空操作必須將新資料列合併至資料表的排序區域，清空所需的時間將隨著資料表變大而增加。您可以透過減少必須合併的資料列數量來改善清空效能。

在清空之前，資料表在資料表的標頭中包含排序的區域，接著是未排序的區域，它會在資料列新增或更新時成長。透過 COPY 操作新增一組資料列時，在新增至資料表尾端的未排序區域時，新的一組資料列會依排序索引鍵排序。新資料列會在其自己的集合內排序，但不會在未排序的區域內排序。

下圖說明兩個後續的 COPY 操作之後的未排序區域，其中的排序索引鍵為 CUSTID。為求簡化，此範例顯示複合排序索引鍵，但相同的原則適用於交錯的排序索引鍵，除了未排序區域的影響大於交錯的資料表。

![\[未排序的資料表，其中保存兩個 COPY 操作的記錄。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/vacuum-unsorted-region.png)


清空會以兩個階段還原資料表的排序順序：

1. 將未排序的區域排序為新排序的區域。

   第一個階段相當經濟實惠，因為只會重新寫入未排序的區域。如果新排序區域的排序索引鍵值的範圍高於現有範圍，則只需要重新寫入新資料列，清空即完成。例如，如果排序的區域包含 ID 值 1 到 500，而和後續的複製操作會新增大於 500 的索引鍵值，那麼只必須重新寫入未排序的區域。

1. 將新排序的區域與先前排序的區域合併。

   如果新排序區域中的索引鍵與排序的區域中的索引鍵重疊，那麼 VACUUM 必須合併資料列。從新排序區域 (最下方的排序索引鍵) 的開頭開始，清空會從將合併的資料列從先前排序的區域和新排序的區域寫入至新的一組區塊。

新排序索引鍵範圍與現有排序索引鍵重疊的程度，決定需要重新寫入先前排序區域的程度。如果未排序的索引鍵分散在現有排序範圍中，清空可能需要重新寫入資料表的現有部分。

下表顯示清空如何排序和合併新增至 CUSTID 為排序索引鍵的資料表的資料列。因為每個複製操作會新增一組新資料列，其具有的索引鍵值與現有索引鍵重疊，幾乎必須重新寫入整個資料表。此表顯示單一的排序和合併，但在實務上，大型的清空包含一系列的遞增排序和合併步驟。

![\[範例資料表上的 VACUUM 操作分為兩個步驟。首先會排序新列，然後與現有列合併。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/vacuum-unsorted-region-sort-merge.png)


如果一組新資料列中排序索引鍵的範圍與現有索引鍵的範圍重疊，合併階段的成本會隨著資料表成長，繼續按比例成長至資料表大小，同時排序階段的成本會維持與未排序區域的大小成比例。在這類情況下，合併階段的成本會使得排序階段的成本相形見絀，如下表所示。

![\[圖表中顯示，當新列擁有的排序索引鍵與現有列重疊時，合併階段成本因而更高。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/vacuum-example-merge-region-grows.png)


若要判斷資料表重新合併的比例，請在清空操作完成之後查詢 SVV\$1VACUUM\$1SUMMARY。下列查詢顯示在 CUSTSALES 隨著時間變大時，六個後續清空的效果。

```
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 會自動新增新資料列至資料表的排序區域：
+ 資料表使用複合排序索引鍵搭配僅一個排序資料欄。
+ 排序資料欄為 NOT NULL。
+ 資料表完全經過排序或為空白。
+ 所有新資料列的排序順序高於現有資料列，包括標記進行刪除的資料列。在此執行個體中，Amazon Redshift 會使用排序索引鍵的前八個位元組來判斷排序順序。
+  COPY 命令不會觸發特定負載最佳化。載入大量資料時，Amazon Redshift 可能會透過建立新的排序分割區來最佳化效能，而不是將資料列新增至資料表的排序區域。

例如，假設您有一個使用客戶 ID 和時間記錄客戶事件的資料表。如果您依客戶 ID 排序，遞增載入新增的新資料列的排序索引鍵範圍很可能會與現有範圍重疊，如先前的範例所示，導致代價高昂的清空操作。

如果您將您的排序索引鍵設為時間戳記資料欄，您的新資料列將以排序順序附加在資料表結尾，如下表所示，降低或甚至消除清空的需求。

![\[使用時間戳記欄作為排序索引鍵的資料表，收到不需要排序的新記錄。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/vacuum-unsorted-region-date-sort.png)


## 使用時間序列資料表來減少儲存的資料
<a name="vacuum-time-series-tables"></a>

如果您維護資料一段時間，使用一系列資料表，如下圖所述。

![\[包含五個季度資料的五個資料表。最舊的資料表會遭到刪除，讓時間維持在一年。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/vacuum-example-unsorted-region-copy-time-series.png)


每次您新增一組資料即建立新的資料表，然後刪除系列中最舊的資料表。您會獲得雙重優勢：
+ 避免刪除資料列的增加成本，因為 DROP TABLE 操作較大量 DELETE 來的更有效。
+ 如果資料表是依時間戳記排序，則不需要清空。如果每個資料表包含一個月的資料，清空將至少必須重新寫入一個月的資料量，即使資料表未依時間戳記排序。

您可以建立 UNION ALL 檢視，供隱藏資料儲存在多個資料表事實的報告查詢使用。如果查詢會依排序索引鍵篩選，查詢規劃器可以有效地略過所有未使用的資料表。UNION ALL 對於其他類型的查詢可能效率較低，因此您應該評估使用該資料表的所有查詢內容中的查詢效能。

# 管理並行寫入操作
<a name="c_Concurrent_writes"></a>

有些應用程式需要的不僅僅是並行查詢和載入，還有並行寫入多個資料表或相同的資料表的能力。在此情況下，*並行*表示重疊，而不是排程在完全相同的時間執行。如果第二個交易在第一個認可之前開始，則會把兩個交易會視為並行。並行操作可能源自受相同使用者或不同使用者控制的不同工作階段。

Amazon Redshift 藉由允許在遞增載入或修改資料表時加以讀取，來支援這些類型的應用程式。查詢只會看到最新認可的資料版本或*快照*，而非等候認可的下一個版本。如果您想要特定查詢等候來自另一個寫入操作的認可，您必須據以排程。

**注意**  
Amazon Redshift 支援預設的*自動遞交*行為，其中每個分開執行的 SQL 命令都會個別遞交。如果您在交易區塊中含括一組命令 (由 [BEGIN](r_BEGIN.md) 和 [結束](r_END.md) 陳述式定義)，該區塊會以一個交易的形式認可，因此您可以在必要時加以復原。這種行為的例外是 TRUNCATE 和 VACUUM 命令，這兩種命令會自動遞交所有目前交易中未完成的變更。  
某些 SQL 用戶端會自動發出 BEGIN 和 COMMIT 命令，讓用戶端控制要將陳述式群組做為交易執行，還是將每個個別的陳述式做為單獨的交易執行。請查看您正在使用的界面文件。例如，使用 Amazon Redshift JDBC 驅動程式時，附帶其中包含多個 (以分號區隔) SQL 命令查詢字串的 JDBC `PreparedStatement` 會將所有陳述式做為單一交易執行。相反地，如果您使用 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 陳述式、DML 命令 (例如 COPY、DELETE、INSERT、UPDATE 和 TRUNCATE)，以及下列 DDL 命令的第一個出現的交易內建立：
+  ALTER TABLE (用來新增或捨棄資料欄) 
+  CREATE TABLE 
+  DROP TABLE 
+  TRUNCATE TABLE 

其他交易無法變更此快照，這表示交易會彼此隔離。也就是說，並行交易彼此看不見對方，也無法偵測到彼此的變更。

任何並行執行交易產生的結果，都必須與依序執行這些交易產生的結果相同。如果這些交易中沒有任何序列執行會產生相同的結果，系統會停止和還原所執行陳述式可能破壞序列化可行性的交易。

例如，假設使用者嘗試執行兩項並行交易：T1 和 T2。執行 T1 和 T2 必須產生相同的結果，至少須符合下列其中一個案例：
+ T1 和 T2 會依照該順序循序執行。
+ T2 和 T1 會依照該順序循序執行。

 Amazon Redshift 中的隔離層級可防止下列問題：
+  已變更讀取 - 當交易讀取尚未認可的資料時，便會發生已變更讀取。例如，假設交易 1 更新一列。交易 2 在 T1 認可更新之前讀取更新的列。如果 T1 復原變更，則 T2 將擁有未認可列中的讀取資料，而 Amazon Redshift 現在將這些資料視為未曾存在。
+  不可重複讀取 - 當單一交易讀取同一列兩次，但倆次得到不同的資料時，便會發生不可重複讀取。例如，假設交易 1 讀取一列。交易 2 更新或刪除該列，並認可更新或刪除。如果 T1 重新讀取該列，則會擷取不同的列值或發現該列已刪除。
+  幽靈 - 幽靈是符合搜尋條件但一開始未看見的列。例如，假設交易 1 讀取一組符合其搜尋條件的列。交易 2 在 UPDATE 或 INSERT 陳述式中產生符合 T1 搜尋條件的新列。如果 T1 重新執行其搜尋陳述式，則會取得一組不同的列。

## SNAPSHOT 和 SERIALIZABLE 隔離
<a name="c_serial_isolation-snapshot_and_serializable"></a>

SERIALIZABLE 和 SNAPSHOT 隔離都是 Amazon Redshift 中提供的可序列化隔離層級。

SNAPSHOT 隔離是建立佈建叢集和無伺服器工作群組時的預設隔離層級，可讓您花較短的時間處理比 SERIALIZABLE 隔離更大的資料量。

SERIALIZABLE 隔離須花較多時間，但對並行交易實施更嚴格的限制。此隔離層級僅允許認可一項交易，同時取消所有其他具有可序列化隔離違規錯誤的並行交易，藉此防止寫入偏斜異常等問題。

以下是使用 SNAPSHOT 隔離時，如何處理兩個並行寫入操作的時間軸範例。允許認可使用者的每個 UPDATE 陳述式，因為其不會嘗試更新相同的列而發生衝突。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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 開始時，資料表 A 存在於資料庫。假設 T2 從 PG\$1TABLES 目錄資料表中進行選取，傳回了資料表清單。然後 T1 捨棄資料表 A 並遞交，然後 T2 再次列出資料表。資料表 A 現在不會再出現在清單中。如果 T2 嘗試查詢已捨棄的資料表，Amazon Redshift 會傳回「關聯不存在」錯誤。傳回資料表的清單至 T2 或檢查資料表 A 存在的類別查詢，不會受限於與對使用者資料表執行的相同隔離規則。

   對這些資料表更新的交易會在讀取已認可隔離模式中執行。
+  PG 字首目錄資料表不支援 SNAPSHOT 隔離。

# 寫入和讀/寫操作
<a name="c_write_readwrite"></a>

透過決定何時與如何執行不同的類型的命令，您可以管理並行寫入操作的特定行為。以下是與此討論相關的命令：
+ COPY 命令，執行載入 (初始或遞增)
+ INSERT 命令，一次附加一或多個資料列
+ UPDATE 命令，修改現有資料列
+ DELETE 命令，移除資料列 

COPY 和 INSERT 操作是純寫入操作。DELETE 和 UPDATE 操作是讀取/寫入操作 (必須先讀取列，才能將其刪除或更新)。並行寫入操作的結果取決於並行執行的特定命令。

UPDATE 和 DELETE 操作有不同的行為，因為它們仰賴於執行任何寫入之前的初始資料表讀取。由於並行交易彼此看不見對方，UPDATE 和 DELETE 必須從上次認可讀取資料的快照。第一個 UPDATE 或 DELETE 釋出其鎖定時，第二個 UPDATE 或 DELETE 必須判斷要使用的資料是否可能過時。它將不會過時，因為第二個交易不會取得其資料的快照，直到第一個交易已釋出其鎖定為止。

## 涉及多個資料表的並行寫入交易潛在死結情況
<a name="c_write_readwrite-potential-deadlock"></a>

只要交易牽涉到一個以上資料表的更新，當其都嘗試寫入相同的資料表集時，並行執行的交易就有可能變成死結。交易會在認可或復原時一次釋出其所有資料表鎖定；它不會一次撤回一個鎖定。

例如，假設交易 T1 和 T2 在大約相同的時間開始。如果 T1 開始寫入資料表，而 T2 開始寫入資料表 B，這兩個交易都可以繼續而不衝突。不過，如果 T1 完成寫入資料表並且必須開始寫入資料表 B，它將無法繼續，因為 T2 仍在 B 上保有鎖定。同樣地，如果 T2 完成寫入資料表 B 並且必須開始寫入資料表 A，它將無法繼續，因為 T1 仍在 A 上保有鎖定。因為這兩項交易都可釋出其鎖定，直到其所有寫入操作都認可，因此兩項交易都無法繼續。為了避免這類的死結，您必須謹慎排程並行寫入操作。例如，您應該一律以相同的順序更新交易中的資料表，同時，如果指定鎖定，在執行任何 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 操作的多項交易在共用鎖定的情況下於相同資料表上並行執行，而其中一項交易遵循其純寫入操作且具有需要獨佔鎖定的操作 (例如 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;
```

如果一或兩個交易包含了 INSERT 命令而非 COPY 命令，可能發生相同的行為。

### 從具有可序列化隔離的相同資料表進行並行 DELETE 操作
<a name="r_Serializable_isolation_example-concurrent-delete-operations-from-the-same-table"></a>

交易 1 會從資料表刪除資料列：

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

交易 2 會並行開始，並嘗試從相同的資料表刪除資料列。它會成功，因為它會在嘗試刪除資料列之前等候交易 1 完成。

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

如果一或兩個交易包含了對相同資料表的 UPDATE 命令而非 DELETE 命令，可能發生相同的行為。

### 混合使用具有可序列化隔離的讀取和寫入操作的並行交易
<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;
```

第二個交易將會成功，因為它必須等候第一個完成。其 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;
```

如果一或兩個交易包含了 INSERT 命令而非 COPY 命令，可能發生相同的行為。

### 從具有快照隔離的相同資料表進行並行 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 偵測到並行工作負載不可序列化。其表明應用程序邏輯中有差距，此問題通常可以透過重試遇到錯誤的交易來解決。如果問題仍然存在，請嘗試使用其他方法。
+ 將任何無須位於同一不可分割交易中的操作，移到交易之外。

  當兩個交易中的個別操作以可能影響另一個交易結果的方式交叉參考時，適用此方法。例如，以下兩個工作階段各自啟動一個交易。

  ```
  Session1_Redshift=# begin;
  ```

  ```
  Session2_Redshift=# begin;
  ```

  每個交易中 SELECT 陳述式的結果，可能會受到另一個交易中 INSERT 陳述式的影響。換句話說，假設您以任何順序，依序執行以下陳述式。在每種情況下，結果都是其中一個 SELECT 陳述式會比同時執行全部交易多傳回一行。依序執行的操作中，沒有任何執行順序可以產生與並行執行相同的結果。因此，最後一個執行的操作會導致可序列化隔離錯誤。

  ```
  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;
  ```

  在這些範例中，交易中沒有交叉參考。兩個 INSERT 陳述式不會互相影響。在這些範例中，至少有一個順序，可讓交易依序執行並產生與並行執行相同的結果。這表示交易是可序列化的。
+ 請透過鎖定每個工作階段中的所有資料表來強制序列化。

  [LOCK](r_LOCK.md) 命令能封鎖可能導致可序列化隔離錯誤的操作。使用 LOCK 命令時，請務必執行以下操作：
  + 鎖定受交易影響的所有資料表，包括受交易內部唯讀 SELECT 陳述式影響的資料表。
  + 無論操作的執行順序為何，均以相同的順序鎖定資料表。
  + 在交易開頭，執行任何操作之前，先鎖定所有資料表。
+ 對並行交易使用快照隔離

  使用 ALTER DATABASE 命令搭配快照隔離。若要深入了解 ALTER DATABASE 的 SNAPSHOT 參數，請參閱 [Parameters](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)。
+ SQL 用戶端，例如 Amazon Redshift 主控台查詢編輯器。

本教學課程設計為可獨立進行。除了本教學課程之外，我們也建議您完成下列教學課程，以便更全面地了解如何設計和使用 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>

如果您已有想要使用的叢集，則可略過此步驟。

針對本教學中的練習，請使用四個節點的叢集。

**建立叢集**

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 的區域。基於本教學的用途，請選擇**美國西部 (奧勒岡)**。

1. 在導覽選單上，選擇**叢集**，然後選擇**建立叢集**。**建立叢集**頁面隨即出現。

1. 在**建立叢集**頁面上輸入叢集的參數。為參數選擇您自己的值，但變更下列值時除外：
   + 選擇 **dc2.large** 作為節點類型。
   + 選擇 **4** 作為**節點數目**。
   + 在**叢集許可**區段中，從**可用 IAM 角色**中選擇 IAM 角色。此角色應為您先前建立的角色，且具備 Amazon S3 的存取權限。然後選擇**與 IAM 角色建立關聯**來將其新增至叢集的**已關聯 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. 下載壓縮檔：[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 管理主控台 ，並在 https：//[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/) 開啟 Amazon S3 主控台。

   1. 選擇**建立儲存貯體**。

   1. 選擇 AWS 區域。

      在和叢集相同的區域中建立儲存貯體。如果叢集位於美國西部 (奧勒岡) 區域，請選擇**美國西部 (奧勒岡) 區域 (us-west-2)**。

   1. 在**建立儲存貯體**對話方塊的**儲存貯體名稱**中，輸入儲存貯體名稱。

      在 Amazon S3 現有的所有儲存貯體名稱中，您選擇的儲存貯體名稱必須是唯一的。其中一種協助確保唯一性的方法是在儲存貯體名稱的前面加上組織名稱。儲存貯體名稱必須符合一些規則。如需詳細資訊，請參閱 [Amazon Simple Storage Service 使用者指南](https://docs.aws.amazon.com/AmazonS3/latest/userguide/BucketRestrictions.html)中的*儲存貯體限制與局限*。

   1. 為其餘選項選擇建議的預設值。

   1. 選擇**建立儲存貯體**。

      當 Amazon S3 成功建立您的儲存貯體，主控台會在**儲存貯體**面板中顯示您的空儲存貯體。

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 命令至少需具備 ListBucket 和 GetObject 許可，才能存取 Amazon S3 儲存貯體中的檔案物件。如需對 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>

在本教學課程中，您會使用以星狀結構描述基準化分析 (SSB) 結構描述為基礎的一組資料表。下圖顯示 SSB 資料模型。

![\[SSB 結構描述的五個資料表及相互之間的關係。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/tutorial-optimize-tables-ssb-data-model.png)


SSB 資料表可能已存在於目前的資料庫中。如果目前資料庫中已有 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 Resource Name (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 format (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>

您會使用下列 COPY 命令載入 SSB 結構描述中的每個資料表。每個資料表的命令分別示範不同的 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>* 取代為與您的叢集位於同一區域的儲存貯體名稱。

   本步驟假設儲存貯體與叢集位於同一區域。或者，您可以使用 [REGION](copy-parameters-data-source-s3.md#copy-region) 選項搭配 COPY 命令來指定區域。

1. 將 *<aws-account-id>* 和 *<role-name>* 取代為您自己的 AWS 帳戶 和 IAM 角色。以單引號括住的登入資料字串區段不可包含任何空格或分行符號。請注意，ARN 的格式可能與範例略有不同。最好從 IAM 主控台複製角色的 ARN，以確保在執行 COPY 命令時正確無誤。

#### 使用 NULL AS 載入 PART 資料表
<a name="tutorial-loading-load-part"></a>

在此步驟中，您將使用 CSV 和 NULL AS 選項載入 PART 資料表。

COPY 命令可以從多個檔案平行載入資料，這比從單一檔案載入更快速。為了示範這個原則，本教學課程將每個資料表中的資料分成八個檔案，即使檔案很小。在稍後的步驟中，您會比較從單一檔案與從多個檔案載入之間的時間差異。如需詳細資訊，請參閱[載入資料檔案](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 format (CSV 格式)**  
CSV 意指以逗號分隔值，是用於匯入和匯出試算表資料的常見格式。CSV 比逗號分隔的格式更有彈性，因為它可讓您在欄位中包含引用字串。從 CSV 格式 COPY 的預設引號字元是雙引號 ( " )，但您可以使用 QUOTE AS 選項指定其他引號字元。在欄位內使用引號字元時，請多加一個引號字元來逸出此字元。

以下摘錄自 PART 資料表的 CSV 格式資料檔案，顯示以雙引號括起來的字串 (`"LARGE ANODIZED BRASS"`)。其也顯示了引用字串中以兩個雙引號括起來的字串 (`"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 失敗的字元。在此練習中，您會對錯誤進行故障診斷，並修正錯誤。

若要載入 CSV 格式的資料，請在 COPY 命令中加入 `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 值的資料表欄設為 *nullable*。也就是說，在 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 )、逗號 ( , ) 或 Tab 字元 ( \$1t )。字元分隔檔案可以使用任可單一 ASCII 字元做為分隔符號，包括其中一個非列印 ASCII 字元。請使用 DELIMITER 選項指定分隔符號。預設分隔符號是縱線字元 ( \$1 )。

下列摘錄自 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` 資料欄中有兩則訊息：
+ 

  ```
  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)
```

這些資料列應該是獨一無二的，但其中有重複。

另一個檢查非預期結果的方法，是去確有已載入的資料列數量。在我們的案例中，應該載入 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/` 資料夾包含 8 個檔案，它們有相同的索引鍵字首 `customer-fw.tbl`：`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. 將檔案上傳到儲存貯體上的 load 資料夾。

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 資料表中的日期格式。注意兩個資料欄的日期格式不一致。

```
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**  
您只能指定一個日期格式。如果載入資料包含不一致的格式 (可能在不同資料欄中)，或是載入時格式未知，請使用 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 選項來載入資料表。

您可以從單一資料檔案或多個檔案載入資料表。執行此操作可比較兩種方法的載入時間。
<a name="tutorial-loading-gzip-lzop"></a>
**GZIP、LZOP 與 BZIP2**  
您可以使用 gzip、lzop 或 bzip2 壓縮格式來壓縮您的檔案。從解壓縮檔案載入時，COPY 會在載入程序中將檔案解壓縮。將檔案壓縮可以節省儲存空間及縮短載入時間。
<a name="tutorial-loading-compupdate"></a>
**COMPUPDATE**  
當 COPY 載入無壓縮編碼的空資料表時，會分析載入資料並決定最佳的編碼。接著它會將資料表修改為使用這些編碼，再開始載入。這個分析程序需要一點時間，但幾乎在每個資料表都會發生一次。若要節省時報，您可以關閉 COMPUPDATE 來略過這個步驟。為了準確評估 COPY 時間，您會在這個步驟中關閉 COMPUPDATE。
<a name="tutorial-loading-multiple-files"></a>
**多個檔案**  
相較於從單一檔案載入資料，COPY 命令從多個檔案平行載入資料更有效率。您可以將您的資料分割為檔案，使得檔案的數量為您叢集中配量數量的倍數。若您執行此作業，Amazon Redshift 會分割工作負載，並在配量中平均分配資料。每一節點的配量數目取決於叢集的節點大小。如需每個節點大小有多少配量的相關資訊，請參閱《Amazon Redshift 管理指南》**中的[關於叢集和節點](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#rs-about-clusters-and-nodes)。

例如，在本教學課程中，您叢集中的運算節點可以各有兩個切片，所以四節點的叢集總共有八個切片。先前的步驟將載入的資料分成八個檔案，即使檔案很小。您可以比較從單一大檔案與從多個檔案載入之間的時間差異。

即使是包含 1500 萬筆記錄且佔用約 1.2 GB 的檔案，對於 Amazon Redshift 規模來說仍非常小。但這些檔案足以示範從多個檔案載入的效能優點。

以下影像顯示 LINEORDER 的資料檔案。

![\[LINEORDER 資料表中的資料分成九個檔案。\]](http://docs.aws.amazon.com/zh_tw/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. 比較執行時間。

   在我們的實驗中，載入 1500 萬筆記錄的時間從 51.56 秒縮短到 17.7 秒，減少了 65.7%。

   這些結果來自於使用具有四個節點的叢集。如果您的叢集有更多節點，節省的時間會加倍。典型的 Amazon Redshift 叢集有數十到數百個節點，差別更巨大。如果您的叢集只有單一節點，執行時間的差異很小。

## 步驟 6：清空及分析資料庫
<a name="tutorial-loading-data-vacuum"></a>

每當您新增、刪除或修改大量資料列時，應先後執行 VACUUM 命令及 ANALYZE 命令。*vacuum* (清空) 會恢復已刪除資料列的空間，並還原排序。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) 