处理架构更新
本节提供了有关为各种数据格式处理架构更新的指导。Athena 是一种基于读取的查询引擎。这意味着,当您在 Athena 中创建一个表时,它会在读取数据时应用架构。它不会改变或者重写底层数据。
如果您期望表架构有所变化,则在创建表架构时应考虑采用一种适合您的需求的数据格式。您的目标是对于不断演进的架构仍能再利用现有的 Athena 查询,同时避免在查询包含分区的表时发生架构不匹配错误。
为实现这些目标,请基于下列主题中的表选择表的数据格式。
支持按数据格式划分的架构更新操作
下表总结了数据存储格式及其支持的架构处理方式。使用此表有助于您选择格式,即使架构随时间发生了变化,也可继续使用 Athena 查询。
在此表中,您可以观察到 Parquet 和 ORC 的列式格式具有不同的默认列访问方法。预设情况下,Parquet 将按名称访问列,ORC 按索引(序数值)访问列。因此,Athena 可在创建表时定义一个 SerDe 属性,以切换默认列访问方法,从而在架构演进的过程中实现更大的灵活度。
对于 Parquet,可将 parquet.column.index.access
属性设为 true
,这样可将列访问方法设置为使用列的序号。将此属性设为 false
会将列访问方法改为使用列名称。同样,ORC 使用 orc.column.index.access
属性控制列访问方法。有关更多信息,请参阅 了解 Apache ORC 和 Apache Parquet 的索引访问权限。
除了将列重新排序或在表的开头添加列之外,可通过 CSV 和 TSV 进行所有其他架构操作。例如,如果架构演进只需要将列重新命名而不需要删除它们,您可以选择创建 CSV 或 TSV 格式的表。如果您需要删除列,请不要使用 CSV 或 TSV,而要使用任何其他支持的格式,最好是列式格式(例如 Parquet 或 ORC)。
架构更新的预期类型 | Summary | CSV(带或不带标头)和 TSV | JSON | AVRO | PARQUET:按名称读取(默认) | PARQUET:按索引读取 | ORC:按索引读取(默认) | ORC:按名称读取 |
---|---|---|---|---|---|---|---|---|
重命名列 | 将您的数据存储为 CSV 和 TSV;或存储为 ORC 和 Parquet(如果按索引读取)。 | Y | 否 | 否 | 否 | Y | Y | 否 |
在表的开头或中间添加新列 | 将您的数据存储为 JSON、AVRO;或存储为 Parquet 和 ORC(如果按名称读取)。不要使用 CSV 和 TSV。 | 否 | Y | Y | Y | 否 | 否 | Y |
在表的末尾添加列 | 将您的数据以 CSV 或 TSV、JSON、AVRO、ORC 或 Parquet 格式存储。 | Y | Y | Y | Y | Y | Y | Y |
删除列 | 将您的数据存储为 JSON、AVRO;或存储为 Parquet 和 ORC(如果按名称读取)。不要使用 CSV 和 TSV。 | 否 | Y | Y | Y | 否 | 否 | Y |
对列重新排序 | 将您的数据存储为 AVRO、JSON;或存储为 ORC 和 Parquet(如果按名称读取)。 | 否 | Y | Y | Y | 否 | 否 | Y |
更改列的数据类型 | 将您的数据存储为任何格式,但请在 Athena 中测试您的查询,以确保数据类型兼容。对于 Parquet 和 ORC,更改数据类型仅适用于分区表。 | Y | Y | Y | Y | Y | Y | Y |
了解 Apache ORC 和 Apache Parquet 的索引访问权限
PARQUET 和 ORC 是列式数据存储格式,可以按索引或名称读取。将数据存储为这两种格式之一,可在执行所有架构操作和运行 Athena 查询时确保不会产生架构不匹配的错误。
-
Athena 预设情况下按索引读取 ORC,如
SERDEPROPERTIES ( 'orc.column.index.access'='true')
中所定义。有关更多信息,请参阅 ORC:按索引读取。 -
Athena 预设情况下按名称读取 Parquet,在
SERDEPROPERTIES ( 'parquet.column.index.access'='false')
中定义。有关更多信息,请参阅 Parquet:按名称读取。
这些是默认设置,因此在您的 CREATE
TABLE
查询中指定这些 SerDe 属性是可选操作,它们是隐式使用的。如果使用这些属性,则允许您运行一些架构更新操作,同时防止其他类似操作。要支持这些操作,请运行另一 CREATE TABLE
查询并更改 SerDe 设置。
注意
这些 SerDe 属性不会自动传播到每个分区。使用 ALTER TABLE ADD PARTITION
语句为每个分区设置 SerDe 属性。要自动执行该流程,请编写一个运行 ALTER TABLE ADD PARTITION
语句的脚本。
以下各部分详细描述了这些情况。
ORC:按索引读取
预设情况下,ORC 格式的表是按索引读取的。这是由以下语法定义的:
WITH SERDEPROPERTIES ( 'orc.column.index.access'='true')
按索引读取允许您将列重新命名。但这样的设置无法删除列或在表的中间添加列。
如果按名称读取 ORC,您就可以在 ORC 表的中间添加列,或删除列,请在 CREATE
TABLE
语句中将 SerDe 属性 orc.column.index.access
设为 false
。如使用此配置,将无法将列重新命名。
注意
在 Athena 引擎版本 2 中,当 ORC 表设置为按名称读取时,Athena 要求 ORC 文件中的所有列名称均为小写。由于 Apache Spark 在生成 ORC 文件时不会使用小写字段名称,因此 Athena 可能无法读取如此生成的数据。解决方法是使用小写对列重命名,或使用 Athena 引擎版本 3。
以下示例演示了如何将 ORC 更改为按名称读取:
CREATE EXTERNAL TABLE orders_orc_read_by_name ( `o_comment` string, `o_orderkey` int, `o_custkey` int, `o_orderpriority` string, `o_orderstatus` string, `o_clerk` string, `o_shippriority` int, `o_orderdate` string ) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde'
WITH SERDEPROPERTIES ( 'orc.column.index.access'='false')
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat' LOCATION 's3://amzn-s3-demo-bucket/orders_orc/';
Parquet:按名称读取
预设情况下,Parquet 格式的表是按名称读取的。这是由以下语法定义的:
WITH SERDEPROPERTIES ( 'parquet.column.index.access'='false')
按名称读取允许您在表中间添加列或删除列。但该设置无法将列重新命名。
要将 Parquet 设为按索引读取,使您可以将列重新命名,则必须在创建表时将 parquet.column.index.access
SerDe 属性设为 true
。