소개
소매업체는 매일 새 파일을 받습니다. 이전 보고서는 각 행 안에 저장된 날짜로 기록을 필터링했습니다. **파티션 테이블(partitioned table)**은 메타데이터에도 날짜별 구성을 기록하므로 쿼리는 요청한 날짜와 연결된 등록 데이터 위치를 선택할 수 있습니다.
HDFS의 파일과 Hive Metastore의 파티션 기록, 두 가지가 일치해야 합니다. Metastore는 테이블 및 파티션 정의를 저장하는 카탈로그입니다. 디렉터리를 만드는 것만으로 Hive 파티션이 등록되지는 않습니다. 새 날짜의 파일을 등록 전에 추가하여 이 차이를 직접 관찰합니다.
이번 실습은 이틀의 파일과 로컬의 셋째 날 데이터를 독립적으로 준비합니다. 파티션 외부 테이블을 만들고 위치를 등록하며 파티션 열을 읽고 필터링한 쿼리 계획을 확인합니다. Hive가 준비되어 있으므로 설치나 이전 VM 상태는 필요하지 않습니다. 외부 테이블과 간단한 날짜 필터를 알면 충분합니다. 터미널을 사용하세요.
파일 열과 파티션 열 구분하기
이 단계에서는 각 기록 안에 날짜를 반복하지 않는 날짜 파티션 테이블을 정의합니다. 준비된 파일을 확인합니다.
cd /home/labex/project
cat /home/labex/project/data/orders-2026-10-14.csv
파일 열은 여섯 개입니다. 이전의 일곱 열 CSV와 달리 이 파일에는 order_date 필드가 없습니다. 파일 하나에는 하루의 주문만 들어 있습니다. 이미 준비된 날짜별 HDFS 디렉터리를 확인합니다.
hdfs dfs -ls /user/labex/hive-partitions/orders
order_date=2026-10-14 같은 디렉터리 이름은 사람이 구성을 읽기 쉽게 합니다. Hive가 이를 사용하려면 여전히 파티션 값과 위치를 등록해야 합니다.
다음 테이블은 여섯 파일 필드를 일반적으로 선언하고 PARTITIONED BY에 order_date DATE를 별도로 선언합니다. Hive는 파티션 메타데이터에서 일곱 번째 조회 가능한 열을 제공합니다. 두 선언에 중복 추가하거나 이 파일들에 일곱 번째 필드를 넣지 마세요.
테이블 정의를 저장하고 실행합니다. 히어 도큐먼트는 SQL 표시 사이의 SQL 텍스트를 그대로 씁니다. Beeline의 -f는 저장한 스크립트를 실행하고 연결 URL과 사용자 이름은 준비된 로컬 Hive 서비스를 가리킵니다.
cat > /home/labex/project/queries/create-partitioned-orders.sql <<'SQL'
CREATE EXTERNAL TABLE retail_partitions.orders (
order_id STRING, customer_id STRING, product_id STRING,
quantity INT, unit_price DECIMAL(10,2), order_status STRING
)
PARTITIONED BY (order_date DATE)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION 'hdfs://localhost:9000/user/labex/hive-partitions/orders'
TBLPROPERTIES ('skip.header.line.count'='1', 'external.table.purge'='false');
SQL
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/create-partitioned-orders.sql
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "DESCRIBE retail_partitions.orders;"
DESCRIBE에는 일반 필드와 파티션 정보가 포함됩니다. 이제 파티션을 등록하기 전에 행 수를 셉니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT COUNT(*) FROM retail_partitions.orders;" > /home/labex/project/output/before-registration.tsv
cat /home/labex/project/output/before-registration.tsv
0이 예상됩니다. 테이블 정의도 있고 기본 디렉터리 아래에 파일도 있지만 새 테이블에 아직 파티션 기록이 없습니다. 이것은 메타데이터의 경계이며 CSV가 삭제되었다는 증거가 아닙니다.
기존의 두 날짜 위치 등록하기
이 단계에서는 각 날짜 값을 실제 디렉터리에 연결합니다. ALTER TABLE ... ADD PARTITION은 Metastore에 파티션 기록을 추가합니다. 각 PARTITION (...)은 날짜 값을 제공하고 LOCATION은 해당 파일을 제공합니다. 값을 각각 명시적으로 지정하므로 정적 파티션입니다.
두 등록을 한 스크립트에 저장합니다.
cat > /home/labex/project/queries/register-first-dates.sql <<'SQL'
ALTER TABLE retail_partitions.orders ADD
PARTITION (order_date='2026-10-14') LOCATION 'hdfs://localhost:9000/user/labex/hive-partitions/orders/order_date=2026-10-14'
PARTITION (order_date='2026-10-15') LOCATION 'hdfs://localhost:9000/user/labex/hive-partitions/orders/order_date=2026-10-15';
SQL
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/register-first-dates.sql
등록된 값을 나열하고 날짜 열을 읽습니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SHOW PARTITIONS retail_partitions.orders;" > /home/labex/project/output/registered-dates.tsv
cat /home/labex/project/output/registered-dates.tsv
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT order_id, order_date FROM retail_partitions.orders ORDER BY order_id;" > /home/labex/project/output/registered-orders.tsv
cat /home/labex/project/output/registered-orders.tsv
SHOW PARTITIONS에는 10월 14일과 15일이 있어야 합니다. 쿼리는 o1–o3에 10월 14일, o4–o6에 10월 15일을 반환합니다. 날짜는 숨겨진 일곱 번째 CSV 필드가 아니라 각 등록 파티션에서 왔습니다.
등록은 기존 데이터를 가리키며 원본 파일을 복사하거나 다시 쓰지 않습니다. 이제 테이블은 대기와 환불 기록을 포함한 주문 여섯 건 모두를 보여줍니다. 결제 완료 판매 보고서에는 여전히 상태 필터가 필요합니다.
먼저 파일을 추가하고 새 날짜 등록하기
이 단계에서는 새 디렉터리와 새 파티션 기록이 별도 작업임을 확인합니다. 준비된 로컬 10월 16일 데이터를 확인합니다.
cat /home/labex/project/data/orders-2026-10-16.csv
HDFS 디렉터리를 만들고 파일을 업로드합니다. 익숙한 이 명령들은 저장소에만 영향을 줍니다.
hdfs dfs -mkdir -p /user/labex/hive-partitions/orders/order_date=2026-10-16
hdfs dfs -put /home/labex/project/data/orders-2026-10-16.csv /user/labex/hive-partitions/orders/order_date=2026-10-16/orders.csv
등록하기 전에 Hive에 그 날짜의 행 수를 묻습니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT COUNT(*) FROM retail_partitions.orders WHERE order_date = DATE '2026-10-16';" > /home/labex/project/output/new-date-before.tsv
cat /home/labex/project/output/new-date-before.tsv
파일을 업로드했어도 0이 예상됩니다. 누락된 메타데이터를 추가하고 날짜별 쿼리를 반복합니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "ALTER TABLE retail_partitions.orders ADD PARTITION (order_date='2026-10-16') LOCATION 'hdfs://localhost:9000/user/labex/hive-partitions/orders/order_date=2026-10-16';"
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SELECT order_id, customer_id, order_status, order_date FROM retail_partitions.orders WHERE order_date = DATE '2026-10-16' ORDER BY order_id;" > /home/labex/project/output/new-date-orders.tsv
cat /home/labex/project/output/new-date-orders.tsv
이제 o7/c1/paid와 o8/c2/pending이 10월 16일과 함께 나타납니다. Hive가 이 파티션 값을 업로드한 디렉터리와 연결할 수 있습니다. 의도적으로 전후를 비교하면 새로 도착한 파일이 HDFS에는 있으면서 보고서에는 빠질 수 있는 이유를 이해할 수 있습니다.
파티션 필터 쿼리와 계획 읽기
이 단계에서는 등록한 날짜 하나를 선택하고 Hive가 요청을 어떻게 계획하는지 살펴봅니다. WHERE에 파티션 열을 사용하는 쿼리를 저장합니다.
cat > /home/labex/project/queries/query-sales-partition.sql <<'SQL'
SELECT order_id, quantity, order_date
FROM retail_partitions.orders
WHERE order_date = DATE '2026-10-15'
ORDER BY order_id;
SQL
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/query-sales-partition.sql > /home/labex/project/output/selected-partition.tsv
cat /home/labex/project/output/selected-partition.tsv
o4/2, o5/1, o6/2가 모두 10월 15일과 함께 예상됩니다. 이것은 날짜 선택이며 아직 결제 완료 판매 필터는 아닙니다. 따라서 환불된 o5가 이 쿼리에 남는 것은 올바릅니다.
EXPLAIN은 데이터 행을 반환하지 않고 쿼리를 설명합니다. DEPENDENCY 옵션은 쿼리가 읽을 테이블과 파티션에 집중합니다. 이 간단한 보기를 사용하면 실행 단계 내부를 먼저 배우지 않고도 입력 선택을 확인할 수 있습니다. 같은 쿼리 앞에 EXPLAIN DEPENDENCY를 붙여 결과를 저장합니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "EXPLAIN DEPENDENCY SELECT order_id, quantity, order_date
FROM retail_partitions.orders
WHERE order_date = DATE '2026-10-15'
ORDER BY order_id;" > /home/labex/project/output/partition-plan.txt
cat /home/labex/project/output/partition-plan.txt
결과는 이름 있는 필드와 목록으로 된 텍스트 형식인 JSON입니다. retail_partitions@orders를 가리키는 input_tables와, 단 하나의 partitionName이 order_date=2026-10-15로 끝나는 input_partitions를 찾으세요. 나머지 두 날짜는 입력 목록에 없습니다. 날짜 조건 덕분에 Hive가 기록을 읽기 전에 관련 등록 파티션을 선택할 수 있으며 이를 **파티션 가지치기(partition pruning)**라고 합니다. 작은 예제는 선택 방식을 이해하기 위한 것이므로 쿼리 시간으로 성능을 비교하는 것은 의미가 없습니다.
마지막으로 등록한 파티션을 다시 나열합니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e "SHOW PARTITIONS retail_partitions.orders;"
세 날짜가 모두 계속 등록되어 있어야 합니다. 날짜 하나를 선택하면 쿼리 입력 선택만 바뀌며 다른 파티션 기록이나 파일을 삭제하지 않습니다. 이제 쿼리가 어느 일일 데이터를 볼 수 있는지 저장소와 카탈로그 양쪽의 증거로 설명할 수 있습니다.
요약
파일 필드와 파티션 열을 분리하고 날짜별 HDFS 위치를 Hive에 등록했으며, 새 디렉터리는 파티션을 추가할 때까지 보이지 않음을 관찰했습니다. 이후 모든 날짜를 보존하면서 날짜 하나를 선택하고 쿼리 계획을 확인했습니다. 다음에는 쿼리 결과를 재사용 가능한 열 기반 ORC 테이블에 저장합니다.



