

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# 在 Amazon Redshift 中卸载数据
<a name="c_unloading_data"></a>

要将数据从数据库表卸载到 Amazon S3 存储桶中的一组文件，可以使用包含 SELECT 语句的 [UNLOAD](r_UNLOAD.md) 命令。不管加载时使用的是何种数据格式，您都可以按分隔格式或固定宽度格式卸载文本数据。此外，您还可以指定是否创建压缩的 GZIP 文件。

您可以使用临时安全凭证限制用户对您的 Amazon S3 存储桶的访问权限。

**Topics**
+ [

# 将数据卸载到 Amazon S3
](t_Unloading_tables.md)
+ [

# 卸载加密的数据文件
](t_unloading_encrypted_files.md)
+ [

# 以分隔或固定宽度格式卸载数据
](t_unloading_fixed_width_data.md)
+ [

# 重新加载卸载的数据
](t_Reloading_unload_files.md)

# 将数据卸载到 Amazon S3
<a name="t_Unloading_tables"></a>

Amazon Redshift 将 SELECT 语句的结果拆分到一组文件（每个节点切片分成一个或多个文件），以便并行重新加载数据。或者，您也可以通过添加 PARALLEL OFF 选项指定 [UNLOAD](r_UNLOAD.md) 将结果串行写入到一个或多个文件。您可以通过指定 MAXFILESIZE 参数来限制 Amazon S3 中文件的大小。UNLOAD 使用 Amazon S3 服务器端加密 (SSE-S3) 自动加密数据文件。

您可以在 UNLOAD 命令中使用 Amazon Redshift 支持的任意 SELECT 语句，但在外部选择中使用 LIMIT 子句的 SELECT 语句除外。例如，您可以使用包含特定列或使用 WHERE 子句联接多个表的 SELECT 语句。如果查询包含引号（例如，引号中含有文本值），则您需要在查询文本中对其进行转义 (\$1')。有关更多信息，请参阅 [SELECT](r_SELECT_synopsis.md) 命令参考。有关使用 LIMIT 子句的更多信息，请参阅 UNLOAD 命令的 [使用说明](r_UNLOAD.md#unload-usage-notes)。

例如，下面的 UNLOAD 命令将 VENUE 表的内容发送到 Amazon S3 存储桶 `s3://amzn-s3-demo-bucket/tickit/unload/`。

```
unload ('select * from venue')   
to 's3://amzn-s3-demo-bucket/tickit/unload/venue_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

上面示例创建的文件名包含前缀“`venue_`”。

```
venue_0000_part_00
venue_0001_part_00
venue_0002_part_00
venue_0003_part_00
```

默认情况下，UNLOAD 根据集群中切片的数量将数据并行写入到多个文件。要将数据写入到单个文件中，请指定 PARALLEL OFF。UNLOAD 按照 ORDER BY 子句（如果使用的话）的绝对排序串行写入数据。数据文件的最大大小为 6.2 GB。如果数据大小超过最大大小，则 UNLOAD 会创建新的文件，每个文件最大可达 6.2 GB。

下面的示例将内容 VENUE 写入到单个文件。文件大小不超过 6.2 GB，因此只需要一个文件。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/tickit/unload/venue_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
parallel off;
```

**注意**  
UNLOAD 命令旨在使用并行处理。对于大多数情况，特别是文件将用于通过 COPY 命令加载表时，我们建议保留 PARALLEL 为启用状态。

假设 VENUE 的总数据大小为 5 GB，下面的示例将 VENUE 的内容写入 50 个文件，每个文件的大小为 100 MB。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/tickit/unload/venue_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
parallel off
maxfilesize 100 mb;
```

如果 Amazon S3 路径字符串中包含前缀，则 UNLOAD 会在文件名中使用该前缀。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/tickit/unload/venue_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

您可以通过在 UNLOAD 命令中指定 MANIFEST 选项来创建列出卸载文件的清单文件。清单是一个 JSON 格式的文本文件，其中显式列出写入到 Amazon S3 的每个文件的 URL。

下面的示例包含了清单选项。

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/tickit/venue_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
manifest;
```

下面的示例显示了四个卸载文件的清单。

```
{
  "entries": [
    {"url":"s3://amzn-s3-demo-bucket/tickit/venue_0000_part_00"},
    {"url":"s3://amzn-s3-demo-bucket/tickit/venue_0001_part_00"},
    {"url":"s3://amzn-s3-demo-bucket/tickit/venue_0002_part_00"},
    {"url":"s3://amzn-s3-demo-bucket/tickit/venue_0003_part_00"}
  ]
}
```

清单文件可用于通过使用包含 MANIFEST 选项的 COPY 来加载相同的文件。有关更多信息，请参阅 [使用清单指定数据文件](loading-data-files-using-manifest.md)。

完成 UNLOAD 操作后，导航到 UNLOAD 写入文件的 Amazon S3 存储桶，确认数据已正确卸载。您会看到一个或多个按切片编号的文件（编号从零开始）。如果您指定了 MANIFEST 选项，则还会看到以“`manifest`”结尾的文件。例如：

```
amzn-s3-demo-bucket/tickit/venue_0000_part_00 
amzn-s3-demo-bucket/tickit/venue_0001_part_00 
amzn-s3-demo-bucket/tickit/venue_0002_part_00 
amzn-s3-demo-bucket/tickit/venue_0003_part_00
amzn-s3-demo-bucket/tickit/venue_manifest
```

您可以在 UNLOAD 完成后调用 Amazon S3 列表操作，以编程方式获取写入到 Amazon S3 的文件的列表。您还可以查询 STL\$1UNLOAD\$1LOG。

下面的查询返回由 UNLOAD 创建的文件的路径名称。[PG\$1LAST\$1QUERY\$1ID](PG_LAST_QUERY_ID.md) 函数返回最新的查询。

```
select query, substring(path,0,40) as path
from stl_unload_log
where query=2320
order by path;

query |             path
-------+--------------------------------------
  2320 | s3://amzn-s3-demo-bucket/venue0000_part_00
  2320 | s3://amzn-s3-demo-bucket/venue0001_part_00
  2320 | s3://amzn-s3-demo-bucket/venue0002_part_00
  2320 | s3://amzn-s3-demo-bucket/venue0003_part_00
(4 rows)
```

如果数据量非常大，Amazon Redshift 可能会将文件按每个切片分成多个部分。例如：

```
venue_0000_part_00
venue_0000_part_01
venue_0000_part_02
venue_0001_part_00
venue_0001_part_01
venue_0001_part_02
...
```

下面的 UNLOAD 命令中的 SELECT 语句中包含带引号的字符串，因此，引号被转义了 (`=\'OH\' '`)。

```
unload ('select venuename, venuecity from venue where venuestate=\'OH\' ')
to 's3://amzn-s3-demo-bucket/tickit/venue/ ' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';
```

默认情况下，UNLOAD 宁可执行失败，也不会覆盖目标存储桶中的现有文件。要覆盖现有文件（包括清单文件），请指定 ALLOWOVERWRITE 选项。

```
unload ('select * from venue') 
to 's3://amzn-s3-demo-bucket/venue_pipe_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
manifest 
allowoverwrite;
```

# 卸载加密的数据文件
<a name="t_unloading_encrypted_files"></a>

UNLOAD 通过采用 AWS 托管式加密密钥的 Amazon S3 服务器端加密（SSE-S3）自动创建文件。您还可以指定利用 AWS Key Management Service 密钥进行服务器端加密 (SSE-KMS)，或利用客户管理的密钥进行客户端加密。UNLOAD 不支持使用客户提供的密钥的 Amazon S3 服务器端加密。有关更多信息，请参阅[使用服务器端加密保护数据](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html)。

要利用 AWS KMS 密钥进行服务器端加密来卸载到 Amazon S3，请如下例所示使用 KMS\$1KEY\$1ID 参数提供密钥 ID。

```
unload ('select venuename, venuecity from venue')
to 's3://amzn-s3-demo-bucket/encrypted/venue_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
KMS_KEY_ID '1234abcd-12ab-34cd-56ef-1234567890ab'
encrypted;
```

如果您希望提供自己的加密密钥，则可以通过使用包含 ENCRYPTED 选项的 UNLOAD 命令在 Amazon S3 中创建客户端加密数据文件。UNLOAD 与 Amazon S3 客户端加密使用相同的信封加密过程。之后，您可以使用包含 ENCRYPTED 选项的 COPY 命令加载加密文件。

该过程的工作方式如下所示：

1. 创建用作私有加密密钥（也称作*根对称密钥*）的 base64 编码的 256 位 AES 密钥。

1. 发出包含根对称密钥及 ENCRYPTED 选项的 UNLOAD 命令。

1. UNLOAD 生成用于加密您的数据的一次性对称密钥（称作*信封对称密钥*）和初始化向量 (IV)。

1. UNLOAD 使用您的根对称密钥加密该信封对称密钥。

1. 然后，UNLOAD 将加密数据文件存储在 Amazon S3 中，并将加密信封密钥和 IV 作为对象元数据随每个文件存储。加密信封密钥作为对象元数据 `x-amz-meta-x-amz-key` 存储，IV 作为对象元数据 `x-amz-meta-x-amz-iv` 存储。

有关信封加密过程的更多信息，请参阅[使用 AWS SDK for Java 和 Amazon S3 进行客户端数据加密](https://aws.amazon.com/articles/2850096021478074)一文。

要卸载加密数据文件，请将根密钥值添加到凭证字符串并包括 ENCRYPTED 选项。如果您使用了 MANIFEST 选项，清单文件也将加密。

```
unload ('select venuename, venuecity from venue')
to 's3://amzn-s3-demo-bucket/encrypted/venue_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
master_symmetric_key '<root_key>' 
manifest
encrypted;
```

要卸载经过 GZIP 压缩的加密数据文件，请包含 GZIP 选项及根密钥值和 ENCRYPTED 选项。

```
unload ('select venuename, venuecity from venue')
to 's3://amzn-s3-demo-bucket/encrypted/venue_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
master_symmetric_key '<root_key>' 
encrypted gzip;
```

要加载加密数据文件，请添加具有相同根密钥值的 MASTER\$1SYMMETRIC\$1KEY 参数，并包括 ENCRYPTED 选项。

```
copy venue from 's3://amzn-s3-demo-bucket/encrypted/venue_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
master_symmetric_key '<root_key>' 
encrypted;
```

# 以分隔或固定宽度格式卸载数据
<a name="t_unloading_fixed_width_data"></a>

您可以按分隔格式或固定宽度格式卸载数据。默认输出为管道分隔（使用“\$1”字符）。

下面的示例将逗号指定为分隔符：

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/tickit/venue/comma' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter ',';
```

这会生成如下所示的输出文件：

```
20,Air Canada Centre,Toronto,ON,0
60,Rexall Place,Edmonton,AB,0
100,U.S. Cellular Field,Chicago,IL,40615
200,Al Hirschfeld Theatre,New York City,NY,0
240,San Jose Repertory Theatre,San Jose,CA,0
300,Kennedy Center Opera House,Washington,DC,0
...
```

要将相同的结果集卸载到制表符分隔的文件中，请发出下面的命令：

```
unload ('select * from venue') 
to 's3://amzn-s3-demo-bucket/tickit/venue/tab' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
delimiter as '\t';
```

或者，您也可以使用 FIXEDWIDTH 规范。该规范包含用于每个表列的分隔符及列的宽度（字符数）。UNLOAD 命令宁可失败也不会截断数据，因此，请指定至少与列的最长条目等长的宽度。卸载固定宽度数据的工作原理与卸载分隔数据相似，只不过生成的输出不包含分隔字符。例如：

```
unload ('select * from venue')
to 's3://amzn-s3-demo-bucket/tickit/venue/fw' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
fixedwidth '0:3,1:100,2:30,3:2,4:6';
```

固定宽度输出如下所示：

```
20 Air Canada Centre         Toronto      ON0
60 Rexall Place              Edmonton     AB0
100U.S. Cellular Field       Chicago      IL40615
200Al Hirschfeld Theatre     New York CityNY0
240San Jose Repertory TheatreSan Jose     CA0
300Kennedy Center Opera HouseWashington   DC0
```

有关 FIXEDWIDTH 规范的更多信息，请参阅 [UNLOAD](r_UNLOAD.md) 命令。

# 重新加载卸载的数据
<a name="t_Reloading_unload_files"></a>

要重新加载卸载操作的结果，您可以使用 COPY 命令。

下面的示例演示了一种简单的情况：使用清单文件卸载 VENUE 表、截断，然后重新加载。

```
unload  ('select * from venue order by venueid')
to 's3://amzn-s3-demo-bucket/tickit/venue/reload_' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole' 
manifest 
delimiter '|';

truncate venue;

copy venue 
from 's3://amzn-s3-demo-bucket/tickit/venue/reload_manifest' 
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
manifest 
delimiter '|';
```

重新加载后，VENUE 表如下所示：

```
select * from venue order by venueid limit 5;

 venueid |         venuename         |  venuecity  | venuestate | venueseats
---------+---------------------------+-------------+------------+-----------
       1 | Toyota Park               | Bridgeview  | IL         |          0
       2 | Columbus Crew Stadium     | Columbus    | OH         |          0
       3 | RFK Stadium               | Washington  | DC         |          0
       4 | CommunityAmerica Ballpark | Kansas City | KS         |          0
       5 | Gillette Stadium          | Foxborough  | MA         |      68756
(5 rows)
```