

# 如何选择分区键
<a name="partition-projection-kinesis-firehose-example-choosing-partition-keys"></a>

您可以指定分区投影如何将分区位置映射到分区键。在上一节的 `CREATE TABLE` 示例中，日期和小时组合成一个名为 datehour 的分区键，但也可以使用其他方案。例如，您还可以为年、月、日和小时配置具有单独分区键的表。

不过，将日期拆分为年、月、日意味着无法使用 `date` 分区投影类型。另一种方法是将日期与小时分开，以便仍然利用 `date` 分区投影类型，但要确保用来指定小时范围的查询更加易于阅读。

考虑到这一点，以下 `CREATE TABLE` 示例将日期与小时分开。由于 `date` 是 SQL 中的保留字，因此这一示例使用 `day` 作为表示日期的分区键的名称。

```
CREATE EXTERNAL TABLE my_ingested_data2 (
 ...
)
...
PARTITIONED BY (
 day STRING,
 hour INT
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.day.type" = "date",
 "projection.day.format" = "yyyy/MM/dd",
 "projection.day.range" = "2021/01/01,NOW",
 "projection.day.interval" = "1",
 "projection.day.interval.unit" = "DAYS",
 "projection.hour.type" = "integer",
 "projection.hour.range" = "0,23",
 "projection.hour.digits" = "2",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${day}/${hour}/"
)
```

在示例 `CREATE TABLE` 语句中，小时是一个单独的分区键，配置为整数。小时分区键的配置指定了 0 到 23 的范围，并且当 Athena 生成分区位置时，小时的格式应为两位数。

对 `my_ingested_data2` 表的查询可能如下所示：

```
SELECT *
FROM my_ingested_data2
WHERE day = '2021/11/09'
AND hour > 3
```

## 了解分区键和分区投影数据类型
<a name="partition-projection-kinesis-firehose-example-partition-key-types-and-partition-projection-types"></a>

请注意，第一个 `CREATE TABLE` 示例中的 `datehour` 键在分区投影配置中配置为 `date`，但分区键的类型为 `string`。第二个示例中的 `day` 也是如此。分区投影配置中的类型仅告诉 Athena 在生成分区位置时如何格式化值。您指定的类型不会更改分区键的类型 – 在查询中，`datehour` 和 `day` 属于 `string` 类型。

当查询包含与 `day = '2021/11/09'` 类似的条件时，Athena 会使用分区投影配置中指定的日期格式解析表达式右侧的字符串。在 Athena 验证日期是否在配置范围内后，它会再次使用日期格式将日期作为字符串插入到存储位置模板中。

同样，对于像 `day > '2021/11/09'` 这样的查询条件，Athena 会解析右侧并生成配置范围内所有匹配日期的列表。然后使用日期格式将每个日期插入到存储位置模板中以创建分区位置列表。

编写与 `day > '2021-11-09'` 或 `day > DATE '2021-11-09'` 相同的条件将无效。在第一种情况下，日期格式不匹配（注意连字符而不是正斜杠），在第二种情况下，数据类型不匹配。