스키마 업데이트 처리 - Amazon Athena

스키마 업데이트 처리

이 단원에서는 다양한 데이터 형식의 스키마 업데이트를 처리하는 방법을 안내합니다. Athena는 스키마-온-리드(schema-on-read) 쿼리 엔진입니다. 즉, Athena에 테이블을 만들면 데이터를 읽을 때 스키마를 적용합니다. 기본 데이터를 변경하거나 다시 작성하지 않습니다.

테이블 스키마 변경이 예측되는 경우, 필요에 적합한 데이터 형식으로 만들어 보세요. 변화하는 스키마에 대해 기존 Athena 쿼리를 다시 사용하고, 파티션이 있는 테이블을 쿼리할 때 스키마 불일치 오류를 방지하는 것이 목표입니다.

이러한 목표를 달성하려면 다음 주제의 테이블을 토대로 테이블의 데이터 형식을 선택합니다.

요약: Athena의 업데이트 및 데이터 형식

다음 표에서는 데이터 스토리지 형식과 지원되는 스키마 조작을 요약합니다. 이 표를 사용하면 시간이 지남에 따라 스키마가 변경되더라도 Athena 쿼리를 계속 사용할 수 있는 형식을 선택하는 데 도움이 됩니다.

이 표에서 Parquet과 ORC가 다른 기본 열 액세스 방법이 서로 다른 열 기반 형식임을 알 수 있습니다. 기본적으로 Parquet은 이름으로 열에 액세스하고 ORC는 인덱스(서수 값)로 액세스합니다. 따라서 Athena는 테이블을 생성할 때 기본 열 액세스 방법을 전환하여 스키마 변화를 통해 유연성을 강화할 수 있도록 정의된 SerDe 속성을 제공합니다.

Parquet의 경우 parquet.column.index.access 속성을 true로 설정하여 열의 서수 번호를 사용하도록 열 액세스 방법을 설정할 수 있습니다. 이 속성을 false로 설정하면 열 이름을 사용하도록 열 액세스 방법이 변경됩니다. 마찬가지로 ORC의 경우 orc.column.index.access 속성을 사용하여 열 액세스 방법을 제어합니다. 자세한 내용은 ORC 및 Parquet에서 인덱스 액세스 단원을 참조하십시오.

CSV 및 TSV를 사용하면 열 순서 변경, 테이블 시작 부분에 열 추가를 제외한 모든 스키마 조작을 수행할 수 있습니다. 예를 들어 스키마 혁신을 위해 열을 제거하지 않고 열 이름만 바꾸면 되는 경우 CSV 또는 TSV로 테이블을 생성할 수 있습니다. 열을 제거해야 하는 경우 CSV 또는 TSV를 사용하지 않고 다른 지원되는 형식 중 Parquet, ORC 등과 같은 열 기반 형식을 사용하는 것이 좋습니다.

Athena의 스키마 업데이트 및 데이터 형식
예상 스키마 업데이트 유형 요약 CSV(헤더 포함 및 불포함) 및 TSV JSON AVRO PARQUET: 이름으로 읽기(기본값) PARQUET: 인덱스로 읽기 ORC: 인덱스로 읽기(기본값) ORC: 이름으로 읽기
열 이름 바꾸기 CSV 및 TSV 또는 ORC 및 Parquet(인덱스로 읽는 경우) 형식으로 데이터를 저장합니다. Y N N N Y Y N
테이블의 시작 또는 중간에 열 추가 JSON, AVRO 또는 Parquet 및 ORC(이름으로 읽는 경우) 형식으로 데이터를 저장합니다. CSV 및 TSV를 사용하지 마세요. N Y Y Y N N Y
테이블 끝에 열 추가 CSV나 TSV, JSON, AVRO, ORC 또는 Parquet 형식으로 데이터를 저장합니다. Y Y Y Y Y Y Y
열 제거 JSON, AVRO 또는 Parquet 및 ORC(이름으로 읽는 경우) 형식으로 데이터를 저장합니다. CSV 및 TSV를 사용하지 마세요. N Y Y Y N N Y
열 재정렬 AVRO, JSON 또는 ORC 및 Parquet(이름으로 읽는 경우) 형식으로 데이터를 저장합니다. N Y Y Y N N Y
열의 데이터 형식 변경 데이터를 어떤 형식으로든 저장하되 Athena에서 쿼리를 테스트하여 데이터 형식이 호환되는지 확인합니다. Parquet과 ORC의 경우 데이터 형식 변경은 분할된 테이블에만 적용됩니다. Y Y Y Y Y Y Y

ORC 및 Parquet에서 인덱스 액세스

PARQUET 및 ORC는 인덱스 또는 이름으로 읽을 수 있는 열 기반 데이터 스토리지 형식입니다. 데이터를 이러한 형식으로 저장하면 스키마에 대한 모든 작업을 수행하고 스키마 불일치 오류 없이 Athena 쿼리를 실행할 수 있습니다.

  • Athena는 SERDEPROPERTIES ( 'orc.column.index.access'='true')에 정의된 대로 기본적으로 인덱스를 기준으로 ORC를 읽습니다. 자세한 내용은 ORC: 인덱스로 읽기 단원을 참조하십시오.

  • Athena는 SERDEPROPERTIES ( 'parquet.column.index.access'='false')에 정의된 대로 기본적으로 이름을 기준으로 Parquet을 읽습니다. 자세한 내용은 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.accessfalse로 설정합니다. 이 구성에서는 열의 이름을 바꿀 수 없습니다.

참고

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://schema_updates/orders_orc/';

Parquet: 이름으로 읽기

기본적으로 Parquet의 테이블은 이름으로 읽습니다. 이는 다음 구문으로 정의됩니다.

WITH SERDEPROPERTIES ( 'parquet.column.index.access'='false')

이름으로 읽기를 사용하면 테이블 중간에 열을 추가하고 열을 제거할 수 있습니다. 하지만 열의 이름을 바꿀 수는 없습니다.

열의 이름을 바꿀 수 있도록 Parquet에서 인덱스로 읽도록 지정하려면 parquet.column.index.access SerDe 속성을 true로 설정하여 테이블을 만들어야 합니다.