Hive 파티션 테이블에 새 필드 추가 및 위치 지정

1. Hive 파티션 테이블 필드 추가

Hive 파티션 테이블에서 필드를 추가하고 특정 위치에 배치하려면 두 단계를 수행해야 합니다: 필드 추가와 필드 위치 변경

1) 필드 추가

ALTER TABLE 테이블이름 ADD COLUMNS (컬럼명 데이터타입 [COMMENT 컬럼코멘트], ...) [CASCADE|RESTRICT];

이 명령은 기존 컬럼 끝에但在分区列之前 새 컬럼을 추가할 수 있습니다

ADD COLUMNS 명령은 Hive 메타데이터만 수정하며, 실제 데이터는 수정하지 않습니다. 테이블/파티션의 실제 데이터 레이아웃이 메타데이터 정의와 일치하는지 확인해야 합니다

2) 필드 변경

ALTER TABLE 테이블이름 CHANGE [COLUMN] 기존컬럼명 새컬럼명 데이터타입 [COMMENT 컬럼코멘트] [FIRST|AFTER 컬럼명] [CASCADE|RESTRICT];

이 명령을 사용하면 컬럼 이름, 데이터 타입, 코멘트 또는 위치를 변경하거나 이들의 조합을 변경할 수 있습니다

CHANGE COLUMN 명령 역시 Hive 메타데이터만 수정하며, 실제 데이터는 수정하지 않습니다. 테이블/파티션의 실제 데이터 레이아웃이 메타데이터 정의와 일치하는지 확인해야 합니다

참고로, 필드 변경 시 일반적으로 비호환 오류가 발생합니다:

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Unable to alter table. The following columns have types incompatible with the existing columns in their respective positions : ...

비호환 상황은 데이터 타입 변환이 호환되지 않거나 컬럼 위치 변경이 호환되지 않는 경우에 발생할 수 있습니다

데이터 타입 변환이 호환되지 않는 경우는 주로 컬럼에 저장된 기존 데이터 타입과 변환하려는 목표 타입 간의 호환성을 의미합니다. 예를 들어, 문자열 타입 컬럼을 정수 타입으로 변환할 때, 문자열 컬럼에 숫자가 포함되어 있으면 변환할 수 있지만, 그렇지 않으면 오류가 발생합니다

필드 타입 변경은 반드시 암시적 변환을 만족해야 합니다. 데이터 정확성 없이 컬럼 타입만 변경하려면 다음 파라미터를 false로 설정합니다 (기본값 true):

set hive.metastore.disallow.incompatible.col.type.changes=false;

컬럼 위치 변경이 호환되지 않는 경우는 주로 Spark on Hive 모드에서 발생합니다. 컬럼 위치 변경은 메타데이터 변경만 있고 (논리적), 실제底层 데이터는 변경되지 않습니다 (물리적).底层 데이터 타입과 메타데이터 타입이 이전과 이후로 일치하지 않아 변경이 허용되지 않습니다. 또한, Spark는 CASCADE 키워드를 지원하지 않습니다

다음은 사용 예제입니다:

CREATE TABLE sample_table (first_col int, second_col int, third_col int);

// 컬럼 first_col의 이름을 new_first로 변경
ALTER TABLE sample_table CHANGE first_col new_first INT;

// 컬럼 new_first의 이름을 converted_col으로 변경하고, 문자열 타입으로 변환하여 second_col 뒤에 배치
ALTER TABLE sample_table CHANGE new_first converted_col STRING AFTER second_col;
// 새 테이블 구조: second_col int, converted_col string, third_col int

// 컬럼 third_col의 이름을 renamed_col으로 변경하고 첫 번째 컬럼으로 배치
ALTER TABLE sample_table CHANGE third_col renamed_col INT FIRST;
// 새 테이블 구조: renamed_col int, second_col int, converted_col string

// 컬럼 new_first에 코멘트 추가
ALTER TABLE sample_table CHANGE new_first new_first INT COMMENT '새로운 첫 번째 컬럼 코멘트';

2. CASCADE 키워드

CASCADE는 "연쇄"를 의미하며, 이름 그대로 연관된 것을 의미합니다. Hive 공식 문서에서 CASCADE 키워드에 대한 설명은 다음과 같습니다:

CASCADE/RESTRICT 하위 문구는 Hive 1.1.0에서 사용 가능합니다. CHANGE COLUMN CASCADE 명령은 테이블 메타데이터의 컬럼을 수정하고 동일한 변경을 모든 파티션 메타데이터에 연쇄적으로 적용합니다. RESTRICT는 기본값으로, 테이블 메타데이터의 컬럼 변경만 제한합니다

CHANGE COLUMN CASCADE 하위 문구는 테이블 또는 파티션의 보호 모드에 관계없이 테이블 파티션의 컬럼 메타데이터를 재정의합니다. 주의해서 사용해야 합니다

자세한 내용은 공식 문서를 참고하세요: https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-AlterColumn

무슨 의미인지 아래 예제로 CASCADE 미사용과 사용의 차이점을 보여줍니다

1) 데이터 준비

create table partition_test (user_id bigint, user_name string) partitioned by (date string);
insert into table partition_test partition (date='2024-11-01') values (1, '가');
insert into table partition_test partition (date='2024-12-01') values (2, '나');
select * from partition_test;
'''
user_id  user_name  date
1        가         2024-11-01
2        나         2024-12-01
'''

2) CASCADE 미사용

alter table partition_test add columns (age int);
insert into table partition_test partition (date='2024-11-01') values (1,'가',19);
insert into table partition_test partition (date='2024-12-01') values (2,'나',18);
insert into table partition_test partition (date='2025-01-01') values (3,'다',20);
select * from partition_test;
'''
user_id  user_name  age  date
1        가         NULL  2024-11-01
1        가         NULL  2024-11-01
2        나         NULL  2024-12-01
2        나         NULL  2024-12-01
3        다         20    2025-01-01
'''

3) CASCADE 사용

alter table partition_test add columns (age int) cascade;
insert into table partition_test partition (date='2024-11-01') values (1,'가',19);
insert into table partition_test partition (date='2024-12-01') values (2,'나',18);
insert into table partition_test partition (date='2025-01-01') values (3,'다',18);
select * from partition_test;
'''
user_id  user_name  age  date
1        가         NULL  2024-11-01
1        가         19    2024-11-01
2        나         NULL  2024-12-01
2        나         18    2024-12-01
3        다         20    2025-01-01
'''

이를 통해 다음과 같은 결론을 얻을 수 있습니다:

  • CASCADE 미사용: 데이터 삽입 시, 기존 데이터가 있는 파티션의 새 필드 값은 NULL이고, 데이터가 없는 파티션의 새 필드 값은 삽입할 수 있습니다
  • CASCADE 사용: 데이터 삽입 시, 기존 데이터가 있는 파티션과 데이터가 없는 파티션 모두 새 필드 값을 성공적으로 삽입할 수 있습니다

즉, 기본값인 RESTRICT는 새 파티션의 테이블 구조만 변경하고 (새 파티션 메타데이터), CASCADE는 새 파티션의 테이블 구조를 변경할 뿐 아니라 (새 파티션 메타데이터), 기존 파티션의 테이블 구조도 연쇄적으로 변경합니다 (기존 파티션 메타데이터)

3. 기존 파티션에 새 컬럼이 NULL로 표시되는 문제

실제 응용 프로그램에서는 일반적으로 테이블 구조 수정 요구 사항이 있습니다, 예를 들어 필드 추가

다음 문을 사용하여 새 컬럼을 추가하면:

ALTER TABLE 테이블이름 ADD COLUMNS (컬럼명 데이터타입 [COMMENT 컬럼코멘트]);

컬럼을 성공적으로 추가할 수 있지만, 테이블에 기존 파티션이 있는 경우 해당 기존 파티션의 새 컬럼은 NULL이 되며 업데이트할 수 없습니다. INSERT OVERWRITE를 사용해도 마찬가지입니다

이 문제가 발생하는 이유는 CASCADE 키워드를 사용하지 않았기 때문입니다. CASCADE는 새 파티션의 테이블 구조를 변경할 뿐 아니라 기존 파티션의 테이블 구조도 연쇄적으로 변경합니다

해결 방법은 간단합니다. 원래 문 뒤에 CASCADE 키워드를 추가하면 됩니다:

ALTER TABLE 테이블이름 ADD COLUMNS (컬럼명 데이터타입 [COMMENT 컬럼코멘트]) CASCADE;

파티션 테이블에 CASCADE 키워드 없이 새 필드를 추가할 때, 기존 파티션에 새로 삽입된 데이터의 새 컬럼 데이터는 모두 NULL로 표시되고, 다른 기존 컬럼 데이터는 정상적으로 표시됩니다

참고로, 새 컬럼 위치를 변경해야 하는 경우에도 CASCADE 키워드를 사용해야 합니다:

ALTER TABLE 테이블이름 CHANGE [COLUMN] 컬럼명 컬럼명 데이터타입 [COMMENT 컬럼코멘트] AFTER 컬럼명 CASCADE;

또한, 저장 형식이 Parquet인 경우 새 컬럼 데이터가 모두 NULL이 되고, TextFile 형식인 경우 이러한 상황이 발생하지 않습니다

태그: Hive Apache Hive DDL partition table metastore

7월 12일 23:40에 게시됨