

# CREATE TABLE
<a name="create-table"></a>

使用您指定的名称和参数创建表。

**注意**  
此页面包含摘要参考信息。有关在 Athena 中创建表的更多信息和示例 `CREATE TABLE` 语句，请参阅[在 Athena 中创建表](creating-tables.md)。有关在 Athena 中创建数据库、创建表和在表上运行 `SELECT` 查询的示例，请参见 [开始使用](getting-started.md)。

## 摘要
<a name="synopsis"></a>

```
CREATE EXTERNAL TABLE [IF NOT EXISTS]
 [db_name.]table_name [(col_name data_type [COMMENT col_comment] [, ...] )]
 [COMMENT table_comment]
 [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
 [CLUSTERED BY (col_name, col_name, ...) INTO num_buckets BUCKETS]
 [ROW FORMAT row_format]
 [STORED AS file_format] 
 [WITH SERDEPROPERTIES (...)]
 [LOCATION 's3://amzn-s3-demo-bucket/[folder]/']
 [TBLPROPERTIES ( ['has_encrypted_data'='true | false',] ['encryption_option'='SSE_S3 | SSE_KMS | CSE_KMS',] ['kms_key'='aws_kms_key_arn',] ['classification'='aws_glue_classification',] property_name=property_value [, ...] ) ]
```

## 参数
<a name="parameters"></a>

**EXTERNAL**  
指定表基于存储在 Amazon S3 中您所指定的 `LOCATION` 中的底层数据文件。除非是创建 [Iceberg](querying-iceberg-creating-tables.md) 表，否则请始终使用 `EXTERNAL` 关键字。如果您将没有 `EXTERNAL` 关键字的 `CREATE TABLE` 用于非 Iceberg 表，Athena 会发出错误。当您创建外部表时，引用的数据必须符合默认格式或您使用 `ROW FORMAT`、`STORED AS` 和 `WITH SERDEPROPERTIES` 子句指定的格式。

**[IF NOT EXISTS]**  
此参数检查是否已存在名称相同的表。如果是，则参数返回 `TRUE`，然后 Amazon Athena 取消 `CREATE TABLE` 操作。由于取消发生在 Athena 调用数据目录之前，因此不会发出 AWS CloudTrail 事件。

**[db\$1name.]table\$1name**  
指定要创建的表的名称。可选的 `db_name` 参数指定表所在的数据库。如果省略，则会采用当前数据库。如果表名称包含数字，请用引号将 `table_name` 引起来，例如 `"table123"`。如果 `table_name` 以下划线开头，请使用反引号，例如 ``_mytable``。不支持特殊字符 (下划线除外)。  
Athena 表名称不区分大小写；但是，如果您使用 Apache Spark，则 Spark 需要小写表名称。有关 Athena 中的表名称的限制，请参阅[命名数据库、表和列](tables-databases-columns-names.md)。

**[ ( col\$1name data\$1type [COMMENT col\$1comment] [, ...] ) ]**  
为要创建的每个列指定名称，以及列的数据类型。列名称不允许下划线 `(_)` 以外的特殊字符。如果 `col_name` 以下划线开头，请将列名称放入反引号内，例如 ``_mycolumn``。有关 Athena 中的列名称的限制，请参阅[命名数据库、表和列](tables-databases-columns-names.md)。  
`data_type` 值可能为以下任一值：  
+ `boolean` – 值为 `true` 和 `false`。
+ `tinyint` – 一个 8 位有符号的整数，采用二进制补码格式，最小值为 -2^7，最大值为 2^7-1。
+ `smallint` – 一个 16 位有符号的整数，采用二进制补码格式，最小值为 -2^15，最大值为 2^15-1。
+ `int` – 在数据定义语言 (DDL) 查询（如 `CREATE TABLE`）中，使用 `int` 关键字来表示整数。在其他查询中，使用关键字 `integer`，其中 `integer` 以二进制补码格式表示为 32 位有符号值，最小值为 -2^31，最大值为 2^31-1。在 JDBC 驱动程序中，将返回 `integer` 以确保与业务分析应用程序兼容。
+ `bigint` – 一个 64 位有符号的整数，采用二进制补码格式，最小值为 -2^63，最大值为 2^63-1。
+ `double` – 64 位有符号的双精度浮点数。范围为 4.94065645841246544e-324d 至 1.79769313486231570e\$1308d，正或负。`double` 遵循 IEEE 浮点算法标准 (IEEE 754)。
+ `float` – 32 位有符号的单精度浮点数。范围为 1.40129846432481707e-45 至 3.40282346638528860e\$138，正或负。`float` 遵循 IEEE 浮点算法标准 (IEEE 754)。相当于 Presto 中的 `real`。在 Athena 中，在 `CREATE TABLE` 等 DDL 语句中使用 `float`，在 `SELECT CAST` 等 SQL 函数中使用 `real`。AWS Glue 爬网程序以 `float` 返回值, Athena 将内部翻译 `real` 和 `float` 类型（请参阅 [2018 年 6 月 5 日](release-notes.md#release-note-2018-06-05) 发布说明）。
+ `decimal [ (precision, scale) ]`，其中 `precision` 是总位数，而 `scale`（可选）是小数部分的位数，默认值为 0。例如，使用以下类型定义：`decimal(11,5)`、`decimal(15)`。最大*精度*值为 38，最大*标度*值为 38。

  要将十进制值指定为文字（例如在查询 DDL 表达式中选择具有特定十进制值的行时），请指定 `decimal` 类型定义，并在查询中将十进制值列为文字（带单引号），如下例所示：`decimal_value = decimal '0.12'`。
+ `char` – 固定长度字符数据，具有介于 1 和 255 之间的指定长度，例如 `char(10)`。有关更多信息，请参阅 [CHAR Hive 数据类型](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types#LanguageManualTypes-char)。
+ `varchar` – 可变长度字符数据，具有介于 1 和 65535 之间的指定长度，例如 `varchar(10)`。有关更多信息，请参阅 [VARCHAR Hive 数据类型](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types#LanguageManualTypes-varchar)。
+ `string` – 用单引号或双引号括起的字符串文本。
**注意**  
在 Athena 中，无法将非字符串数据类型强制转换为 `string`；而是将这些数据类型强制转换为 `varchar`。
+ `binary` –（适用于 Parquet 中的数据）
+ `date` – ISO 格式的日期，例如 `YYYY-MM-DD`。例如 `date '2008-09-15'`。OpenCSVSerDe 是一个例外，它使用自 1970 年 1 月 1 日以来经过的天数。有关更多信息，请参阅 [用于处理 CSV 的 Open CSV SerDe](csv-serde.md)。
+ `timestamp` – 使用 [https://docs.oracle.com/javase/8/docs/api/java/sql/Timestamp.html](https://docs.oracle.com/javase/8/docs/api/java/sql/Timestamp.html) 兼容格式的瞬间日期和时间最多可达毫秒级的最大分辨率，例如 `yyyy-MM-dd HH:mm:ss[.f...]`。例如 `timestamp '2008-09-15 03:04:05.324'`。OpenCSVSerDe 是一个例外，它使用UNIX 数字格式的 `TIMESTAMP` 数据（例如 `1579059880000`）。有关更多信息，请参阅 [用于处理 CSV 的 Open CSV SerDe](csv-serde.md)。
+ `array` < data\$1type >
+ `map` < primitive\$1type, data\$1type >
+ `struct`< col\$1name : data\$1type [comment col\$1comment] [, ...]>

**[COMMENT table\$1comment]**  
创建 `comment` 表属性并用您指定的 `table_comment` 填充它。

**[PARTITIONED BY (col\$1name data\$1type [ COMMENT col\$1comment ], ... ) ]**  
使用指定了 `col_name`、`data_type` 和 `col_comment` 的一个或多个分区列创建分区表。一个表可以有一个或多个分区，这些分区由多个不同的列名称和值组合组成。将会为每个指定的组合创建一个单独的数据目录，这在某些情况下可提高查询性能。已分区列在表数据本身中不存在。如果您将与表列相同的某个值用于 `col_name`，则会产生错误。有关更多信息，请参阅[分区数据](partitions.md)。  
在您创建具有分区的表后，请运行后续查询，其中包含 [MSCK REPAIR TABLE](msck-repair-table.md) 子句用以刷新分区元数据，例如，`MSCK REPAIR TABLE cloudfront_logs;`。对于不兼容 Hive 的分区，请使用 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 加载分区，以便您可以查询数据。

**[CLUSTERED BY (col\$1name, col\$1name, ...) INTO num\$1buckets BUCKETS]**  
在使用分区或不使用分区的情况下，将指定 `col_name` 列中的数据分成名为*存储桶*的数据子集。`num_buckets` 参数指定要创建的存储桶数量。分桶可以提高对大型数据集的某些查询的性能。

**[ROW FORMAT row\$1format]**  
指定表及其底层源数据 (如果适用) 的行格式。对于 `row_format`，您可以使用 `DELIMITED` 子句指定一个或多个分隔符，或者如下所述使用 `SERDE` 子句。如果省略 `ROW FORMAT` 或指定 `ROW FORMAT DELIMITED`，则会使用本机 SerDe。  
+ [DELIMITED FIELDS TERMINATED BY char [ESCAPED BY char]]
+ [DELIMITED COLLECTION ITEMS TERMINATED BY char]
+ [MAP KEYS TERMINATED BY char]
+ [LINES TERMINATED BY char]
+ [NULL DEFINED AS char]

  仅当使用 Hive 0.13 且 STORED AS 文件格式为 `TEXTFILE` 时才可用。
 **或者**   
+ SERDE 'serde\$1name' [WITH SERDEPROPERTIES ("property\$1name" = "property\$1value", "property\$1name" = "property\$1value" [, ...] )]

  `serde_name` 指示要使用的 SerDe。`WITH SERDEPROPERTIES` 子句能让您提供 SerDe 允许的一个或多个自定义属性。

**[STORED AS file\$1format]**  
为表数据指定文件格式。如果省略，则 `TEXTFILE` 是默认值。`file_format` 的选项是：  
+ SEQUENCEFILE
+ TEXTFILE
+ RCFILE
+ ORC
+ PARQUET
+ AVRO
+ ION
+ INPUTFORMAT input\$1format\$1classname OUTPUTFORMAT output\$1format\$1classname

**[LOCATION 's3://amzn-s3-demo-bucket/[folder]/']**  
指定从中创建表的底层数据在 Amazon S3 中的位置。位置路径必须是存储桶名称或存储桶名称以及一个或多个文件夹。如果您使用分区，请指定分区数据的根目录。有关表位置的更多信息，请参阅[指定 Amazon S3 中的表位置](tables-location-format.md)。有关数据格式和权限的信息，请参阅 [Amazon S3 注意事项](creating-tables.md#s3-considerations)。  
为您的文件夹或存储桶使用尾部斜杠。请勿使用文件名或 glob 字符。  
 **使用**:  
`s3://amzn-s3-demo-bucket/`  
`s3://amzn-s3-demo-bucket/folder/`  
`s3://amzn-s3-demo-bucket/folder/anotherfolder/`  
 **请勿使用：**  
`s3://amzn-s3-demo-bucket`  
`s3://amzn-s3-demo-bucket/*`  
`s3://amzn-s3-demo-bucket/mydatafile.dat`

**[TBLPROPERTIES ( ['has\$1encrypted\$1data'='true \$1 false',] ['encryption\$1option'='SSE\$1S3 \$1 SSE\$1KMS \$1 CSE\$1KMS',] ['kms\$1key'='aws\$1kms\$1key\$1arn',] ['classification'='classification\$1value',] property\$1name=property\$1value [, ...] ) ]**  
除预定义的表属性外，还指定表定义的自定义元数据键-值对，例如 `"comment"`。  
**has\$1encrypted\$1data** – Athena 有一个内置属性 `has_encrypted_data`。将此属性设置为 `true` 以指示 `LOCATION` 指定的底层数据集是 CSE-KMS 加密的。如果省略，并且如果工作组的设置不覆盖客户端设置，则假设 `false`。如果加密了底层数据时将它省略或设置为 `false`，则查询会导致错误。有关更多信息，请参阅 [静态加密](encryption.md)。  
**encryption\$1option**：将此属性设置为 `SSE_S3`、`SSE_KMS` 或 `CSE_KMS`，以表示由 `LOCATION` 指定的底层数据集中使用的最高加密级别。有关更多信息，请参阅 [静态加密](encryption.md)。  
**kms\$1key**：将此属性设置为用于加密和解密表数据文件的 AWS KMS 密钥 ARN。使用 `SSE_KMS` 或 `CSE_KMS` 加密写入时，Athena 使用此密钥加密表数据文件，以及解密 CSE-KMS 加密的表数据文件。仅当 `encryption_option` 设置为 `SSE_KMS` 或 `CSE_KMS` 时需要此属性。有关更多信息，请参阅 [静态加密](encryption.md)。  
**classification** – 在 CloudTrail 控制台中为 Athena 创建的表将 `cloudtrail` 添加为 `classification` 属性的值。为运行 ETL 任务，AWS Glue 要求您创建一个具有 `classification` 属性的表来将 AWS Glue 的数据类型指示为 `csv`、`parquet`、`orc`、`avro` 或 `json`。例如 `'classification'='csv'`。如果您不指定此属性，则 ETL 任务将会失败。随后，您可以使用 AWS Glue 控制台、API 或 CLI 来指定它。有关更多信息，请参阅 [为 ETL 作业创建表](schema-classifier.md)和《AWS Glue 开发人员指南》**中的[在 AWS Glue 中编写任务](https://docs.aws.amazon.com/glue/latest/dg/author-job.html)。  
**compression\$1level** – `compression_level` 属性指定了要使用的压缩级别。此属性仅适用于 ZSTD 压缩。可能的值介于 1 和 22 之间。默认值为 3。有关更多信息，请参阅 [使用 ZSTD 压缩级别](compression-support-zstd-levels.md)。  
有关其他表属性的更多信息，请参阅 [ALTER TABLE SET TBLPROPERTIES](alter-table-set-tblproperties.md)。

## 示例
<a name="create-table-examples"></a>

以下示例 `CREATE TABLE` 语句会基于存储在 Amazon S3 中的制表符分隔的行星数据创建一个表。

```
CREATE EXTERNAL TABLE planet_data (
  planet_name string,
  order_from_sun int,
  au_to_sun float,
  mass float,
  gravity_earth float,
  orbit_years float,
  day_length float
  )
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE
LOCATION 's3://amzn-s3-demo-bucket/tsv/'
```

请注意以下几点：
+ `ROW FORMAT DELIMITED` 子句指示数据由特定字符分隔。
+ `FIELDS TERMINATED BY '\t'` 子句指定 TSV 数据中的字段由制表符 ('\$1t') 分隔。
+ `STORED AS TEXTFILE` 子句指示数据以纯文本文件的形式存储在 Amazon S3 中。

要查询数据，可以使用如下所示的简单 `SELECT` 语句：

```
SELECT * FROM planet_data
```

要使用该示例在 Athena 中创建您自己的 TSV 表，请将表和列名替换为您自己的表和列的名称和数据类型，并更新 `LOCATION` 子句以指向存储 TSV 文件的 Amazon S3 路径。

有关创建表的更多信息，请参阅 [在 Athena 中创建表](creating-tables.md)。