

# 更改列数据类型
<a name="updates-changing-column-type"></a>

当现有类型无法再容纳所需的信息量时，您可能需要使用其他列类型。例如，ID 列的值可能超过 `INT` 数据类型的大小，需要使用 `BIGINT` 数据类型。

## 注意事项
<a name="updates-changing-column-type-considerations"></a>

在计划为列使用不同的数据类型时，请考虑以下几点：
+ 在大多数情况下，不能直接更改列的数据类型。而是可以重新创建 Athena 表，并使用新的数据类型定义该列。
+ 只有特定数据类型可以读取为其他数据类型。有关可以进行这种处理的数据类型，请参阅本部分中的表。
+ 对于 Parquet 和 ORC 格式的数据，如果表未进行分区，则将无法为列使用其他数据类型。
+ 对于 Parquet 和 ORC 格式的分区表，一个分区的列类型可以不同于另一个分区的列类型，而且 Athena 将 `CAST` 为所需的类型（如果可能）。有关信息，请参阅[避免带有分区的表出现架构不匹配错误](updates-and-partitions.md#partitions-dealing-with-schema-mismatch-errors)。
+ 对于仅使用 [LazySimpleSerDe](lazy-simple-serde.md) 创建的表，可以使用 `ALTER TABLE REPLACE COLUMNS` 语句将现有列替换为不同的数据类型，但是还必须在语句中重新定义要保留的所有现有列，否则它们将被删除。有关更多信息，请参阅 [ALTER TABLE REPLACE COLUMNS](alter-table-replace-columns.md)。
+ 仅对于 Apache Iceberg 表而言，您可以使用 [ALTER TABLE CHANGE COLUMN](querying-iceberg-alter-table-change-column.md) 语句更改列的数据类型。`ALTER TABLE REPLACE COLUMNS` 不支持 Iceberg 表。有关更多信息，请参阅 [Iceberg 表架构演进](querying-iceberg-evolving-table-schema.md)。

**重要**  
我们强烈建议您在执行数据类型转换时，先测试和验证一下您的查询。如果 Athena 无法使用目标数据类型，则 `CREATE TABLE` 查询可能会失败。

## 使用兼容的数据类型
<a name="updates-changing-column-type-use-compatible-data-types"></a>

尽可能使用兼容的数据类型。下表列出了可被视为其他数据类型的数据类型：


| 原始数据类型 | 可用的目标数据类型 | 
| --- | --- | 
| STRING | BYTE, TINYINT, SMALLINT, INT, BIGINT | 
| BYTE | TINYINT, SMALLINT, INT, BIGINT | 
| TINYINT | SMALLINT, INT, BIGINT | 
| SMALLINT | INT, BIGINT | 
| INT | BIGINT | 
| FLOAT | DOUBLE | 

以下示例为原始 `orders_json` 表使用 `CREATE TABLE` 语句创建一个名为 `orders_json_bigint` 的新表。新表使用 `BIGINT` 而不是 `INT` 作为 ``o_shippriority`` 列的数据类型。

```
CREATE EXTERNAL TABLE orders_json_bigint (
   `o_orderkey` int, 
   `o_custkey` int, 
   `o_orderstatus` string, 
   `o_totalprice` double, 
   `o_orderdate` string, 
   `o_orderpriority` string, 
   `o_clerk` string, 
   `o_shippriority` BIGINT
) 
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://amzn-s3-demo-bucket/orders_json';
```

以下查询可成功运行，与更改数据类型前的原始 `SELECT` 查询类似：

```
Select * from orders_json 
LIMIT 10;
```