

# 根据 Amazon S3 中的加密数据集创建表
<a name="creating-tables-based-on-encrypted-datasets-in-s3"></a>

Athena 可以读取和写入底层数据集采用 SSE-S3、SSE-KMS 或 CSE-KMS 加密的表。根据表数据使用的加密选项和运行的查询类型，您可能需要指定一些其他表属性才能读取和写入加密数据。

## 读取 SSE-S3/SSE-KMS 加密表
<a name="reading-sse-s3-sse-kms-encrypted-tables"></a>

创建表时无需指定其他表属性即可读取 SSE-S3/SSE-KMS 加密数据集。Amazon S3 会自动处理 SSE 对象的解密。

## 读取 CSE-KMS 加密表
<a name="reading-cse-kms-encrypted-tables"></a>

为使 Athena 能够读取 CSE-KMS 加密数据集，可以指定两组不同的表属性：
+ 使用 `encryption_option` 和 `kms_key` 表属性（推荐）
+ 使用 `has_encrypted_data` 表属性

**重要**  
如果使用 Amazon EMR 以及 EMRFS 上传 CSE-KMS 加密的 Parquet 文件，则必须通过将 `fs.s3n.multipart.uploads.enabled` 设置为 `false` 来禁用分段上传。如果您未执行此操作，则 Athena 无法确定 Parquet 文件长度，将出现 **HIVE\$1CANNOT\$1OPEN\$1SPLIT** 错误。有关更多信息，请参阅《Amazon EMR 管理指南》**中的[为 Amazon S3 配置分段上传](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#Config_Multipart)。

### 使用 encryption\$1option 和 kms\$1key 表属性
<a name="using-encryption-option-and-kms-key-table-properties"></a>

在 [CREATE TABLE](create-table.md) 语句中，请使用 `TBLPROPERTIES` 子句指定 `encryption_option='CSE_KMS'` 和 `kms_key='aws_kms_key_arn'`，如以下示例所示。

```
CREATE EXTERNAL TABLE 'my_encrypted_data' (
   `n_nationkey` int,
   `n_name` string,
   `n_regionkey` int,
   `n_comment` string)
ROW FORMAT SERDE
   'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
LOCATION
   's3://amzn-s3-demo-bucket/folder_with_my_encrypted_data/'
TBLPROPERTIES (
    'encryption_option' = 'CSE_KMS',
    'kms_key' = 'arn:aws:kms:us-east-1:012345678901:key/my_kms_key')
```

配置这些属性后：
+ Athena 可以读取由 V1、V2 或 V3 Amazon S3 加密客户端创建的 CSE-KMS 加密对象。
+ Athena 将使用 `kms_key` 中的 AWS KMS 密钥来解密 CSE-KMS 数据。如果任何对象使用不同的 AWS KMS 密钥加密，则查询将失败。
+ Athena 仍然可以读取 SSE-S3 和 SSE-KMS 加密对象，但不建议混合使用服务器端和客户端加密对象。

### 使用 has\$1encrypted\$1data 表属性
<a name="using-has-encrypted-data-table-property"></a>

在 [CREATE TABLE](create-table.md) 语句，请使用 `TBLPROPERTIES` 子句指定 `has_encrypted_data='true'`，如以下示例所示。

```
CREATE EXTERNAL TABLE 'my_encrypted_data' (
   `n_nationkey` int,
   `n_name` string,
   `n_regionkey` int,
   `n_comment` string)
ROW FORMAT SERDE
   'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
LOCATION
   's3://amzn-s3-demo-bucket/folder_with_my_encrypted_data/'
TBLPROPERTIES (
    'has_encrypted_data' = 'true')
```

指定 has\$1encrypted\$1data 表属性时：
+ Athena 只能读取由 V1 Amazon S3 加密客户端创建的 CSE-KMS 加密对象。
+ Athena 将从对象元数据中推断出用于加密 CSE-KMS 对象的 AWS KMS 密钥，然后使用该密钥解密对象。
+ Athena 仍然可以读取 SSE-S3 和 SSE-KMS 加密对象，但不建议混合使用服务器端和客户端加密对象。

**注意**  
当 `encryption_option` 和 `kms_key` 与 `has_encrypted_data` 同时指定时，`encryption_option` 和 `kms_key` 表属性优先，而 `has_encrypted_data` 将被忽略。

使用 Athena 控制台[使用表单创建表](data-sources-glue-manual-table.md)并指定表位置时，请选择**加密的数据集**选项，将 `has_encrypted_data='true'` 属性添加到表格。

![\[在添加表单项中选择 Encrypted data set（加密的数据集）\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/add-table-form-encrypted-option.png)


在 Athena 控制台的表列表中，CSE-KMS 加密的表含有 `has_encrypted_data='true'`，显示钥匙形图标。

![\[加密表图标\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/tables-list-encrypted-table-icon.png)


## 写入 SSE-S3/SSE-KMS/CSE-KMS 加密数据
<a name="writing-sse-s3-sse-kms-cse-kms-encrypted-data"></a>

默认情况下，新插入的数据文件将使用 Athena 工作组中指定的查询结果加密配置进行加密。要使用与查询结果加密配置不同的加密配置来写入表数据，必须添加一些其他表属性。

在 [CREATE TABLE](create-table.md) 语句中，请使用 `TBLPROPERTIES` 子句指定 `encryption_option='SSE_S3 | SSE_KMS | CSE_KMS'` 和 `kms_key='aws_kms_key_arn'`，如以下示例所示。

```
CREATE EXTERNAL TABLE 'my_encrypted_data' (
   `n_nationkey` int,
   `n_name` string,
   `n_regionkey` int,
   `n_comment` string)
ROW FORMAT SERDE
   'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
   'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
LOCATION
   's3://amzn-s3-demo-bucket/folder_with_my_encrypted_data/'
TBLPROPERTIES (
    'encryption_option' = 'SSE_KMS',
    'kms_key' = 'arn:aws:kms:us-east-1:012345678901:key/my_kms_key')
```

所有新插入的数据都将使用表属性指定的加密配置进行加密，而不是使用工作组中查询结果的加密配置。

## 注意事项和限制
<a name="considerations-and-limitations"></a>

写入和读取加密数据集时，请考虑以下几点。
+ `has_encrypted_data`、`encryption_option` 和 `kms_key` 表属性只能用于 Hive 表。
+ 创建包含 CSE-KMS 加密数据的表时，我们建议您确保使用相同的 AWS KMS 密钥加密所有数据。
+ 创建包含 CSE-KMS 加密数据的表时，我们建议您确保所有数据均采用 CSE-KMS 加密，不混合使用非 CSE-KMS 和 CSE-KMS 加密对象。