소개
소매업체의 주문 기록을 스프레드시트로 연다고 생각해 보세요. 각 행은 주문 하나를 설명하고 각 열은 날짜나 결제 상태 같은 속성을 나타냅니다. 여러분은 **팀이 어떤 결제 완료 주문부터 검토해야 할까?**라는 간단한 질문에 답하려고 합니다. 파일이 커질수록 모든 행을 직접 읽기는 불편해집니다.
Apache Hive를 사용하면 파일 데이터를 테이블로 정의하고 구조화 질의 언어인 **SQL(Structured Query Language)**로 질문할 수 있습니다. 테이블 정의는 열과 실제 파일의 위치를 설명하고, 파일에는 실제 기록이 들어 있습니다. Hive는 이 정의를 사용하여 데이터를 해석하고 쿼리를 실행합니다. 준비된 환경에서 HDFS는 저장소를 제공하고 Hive는 테이블과 쿼리 계층을 제공합니다. 파일을 업로드하는 것만으로 Hive 테이블이 자동으로 만들어지지는 않습니다.
Hive는 배치 보고서처럼 저장된 데이터에 대한 분석 쿼리에 유용합니다. 스프레드시트의 셀을 편집하는 것과 같지는 않으며, 이 과정에서는 모든 애플리케이션의 트랜잭션 데이터베이스를 대체하는 도구로 소개하지 않습니다. 여기서는 읽기 쉬운 여섯 기록으로 시작하므로 더 큰 입력을 다루기 전에 올바른 답을 예상할 수 있습니다.
Hive의 터미널 클라이언트 Beeline으로 실행 중인 HiveServer2 서비스에 연결합니다. 서비스와 예제 테이블이 준비되어 있습니다. 소프트웨어를 설치하거나 메타데이터를 초기화할 필요가 없으며 Java, Python, Hadoop 또는 SQL을 미리 알 필요도 없습니다. 기본 터미널 사용법과 표를 읽는 능력이면 충분합니다. 터미널이나 데이터베이스를 더 연습하려면 Linux와 Database 경로를 참고하세요.
학습 순서는 실제 행 보기, 테이블 구조 알아보기, 결제된 주문을 선택하는 쿼리 저장하기, 조건 하나를 바꾸어 이해도 확인하기입니다.
첫 Hive 행 살펴보기
이 단계에서는 쿼리 범위를 좁히는 방법을 배우기 전에 Hive에 연결하여 준비된 테이블을 읽습니다.
Terminal 탭을 사용하세요. cd로 로컬 프로젝트 디렉터리로 이동합니다.
cd /home/labex/project
Beeline은 클라이언트입니다. SQL을 HiveServer2에 보내면 서비스가 쿼리를 처리합니다. 아래 명령에서 -u는 연결 URL, -n은 세션 사용자 이름, -e는 실행한 뒤 터미널로 돌아오기 전에 처리할 SQL을 제공합니다. 주어진 URL은 이 컴퓨터의 포트 10000에 있는 Hive 서비스에 연결하며 처음에는 default 데이터베이스를 사용합니다. 이 학습 서비스에는 외부 계정이나 비밀번호가 필요하지 않습니다.
SQL SELECT * FROM retail_intro.orders;는 retail_intro 데이터베이스의 orders 테이블에서 모든 열(*)을 요청합니다. 세미콜론은 문장을 끝냅니다. 작은따옴표는 SQL 문장 전체를 셸 인수 하나로 유지합니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'SELECT * FROM retail_intro.orders;'
주문 여섯 행과 order_id, quantity, order_status 같은 열 이름을 찾으세요. 결과 주변에는 연결 메시지와 표 테두리가 나타날 수 있습니다. 주문 o1을 찾으면 수량은 2, 단가는 10.00, 상태는 결제 완료를 뜻하는 paid입니다. o3은 대기 중인 pending, o5는 환불된 refunded입니다. 각 행은 상품 유형 하나를 포함하는 단순화된 주문 한 건입니다.
쿼리는 데이터를 가져옵니다. 이 SELECT는 결제 상태를 바꾸거나 원본 파일을 갱신하지 않습니다. 정렬 절이 없으면 SQL이 특정 행 순서를 보장한다고 가정하지 마세요.
같은 쿼리 출력을 로컬 기록 파일에 저장합니다. 셸의 > 연산자는 파일을 만들거나 기존 내용을 바꿉니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'SELECT * FROM retail_intro.orders;' > /home/labex/project/output/first-look.txt
로컬에서 읽습니다.
cat /home/labex/project/output/first-look.txt
주문 행이 여전히 보여야 합니다. 터미널은 Beeline 클라이언트를 실행했고, Hive는 테이블 정의와 파일을 읽었으며, 셸은 표시된 결과를 로컬에 저장했습니다. 다음으로 쿼리 뒤에 있는 객체를 알아봅니다.
데이터베이스, 테이블과 열 알아보기
이 단계에서는 열 이름을 추측하는 대신 데이터베이스와 테이블 정의를 살펴봅니다.
**데이터베이스(database)**는 테이블을 묶는 이름 공간입니다. SHOW DATABASES는 사용 가능한 데이터베이스를 나열하며 모든 데이터 파일을 읽지는 않습니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'SHOW DATABASES;'
default와 retail_intro를 찾으세요. USE로 데이터베이스를 선택하고 같은 호출에서 SHOW TABLES를 이어서 실행합니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'USE retail_intro; SHOW TABLES;'
orders가 있어야 합니다. -e 명령마다 새 Beeline 세션을 열므로 한 호출의 USE가 다음 호출로 자동으로 이어지지 않습니다. SQL 파일마다 데이터베이스를 선택하거나 전체 이름인 retail_intro.orders를 사용하세요.
DESCRIBE는 테이블 열과 자료형을 나열합니다. 예를 들어 STRING은 텍스트, INT는 정수, DECIMAL(10,2)는 소수점 아래 두 자리를 갖는 고정 소수점 수를 저장하고 DATE는 달력 날짜를 나타냅니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'DESCRIBE retail_intro.orders;'
첫 쿼리의 행과 필드를 연결해 보세요. 수량과 가격은 둘 다 숫자처럼 보여도 의미와 자료형이 다릅니다. 금액 계산은 이후 실습에서 하고 오늘은 제공된 필드만 읽습니다.
쿼리 결과를 저장할 때 Beeline은 간단한 텍스트 형식을 사용할 수 있습니다. --outputformat=tsv2는 탭 구분 필드를 선택하고, --showHeader=false는 헤더 행을 생략하며, --silent=true는 클라이언트 메시지를 줄입니다. 이러한 출력 옵션으로 스키마 설명을 저장합니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -e 'DESCRIBE retail_intro.orders;' > /home/labex/project/output/table-schema.txt
기록 파일에 실행 메시지도 포함될 수 있습니다. 중요한 스키마 행에는 일곱 열 모두의 이름과 자료형이 있습니다. 테이블 정의는 메타데이터이며, 저장된 파일을 어떻게 해석할지 Hive에 알려 줍니다. 다음 실습에서는 이 연결을 직접 만드는 방법을 배웁니다.
먼저 검토할 결제 완료 주문 쿼리 저장하기
이 단계에서는 검토팀에 필요한 열과 결제 완료 행만 선택하고 예측 가능한 결과 순서를 지정합니다.
쿼리는 서로 독립적인 여러 방식으로 데이터 범위를 좁힐 수 있습니다.
| 절 | 이번 실습의 용도 |
|---|---|
SELECT |
출력 열 선택 |
FROM |
원본 테이블 선택 |
WHERE |
조건이 참인 행 유지 |
ORDER BY |
결과를 명시적으로 정렬 |
LIMIT |
요청한 수 이하의 행 반환 |
order_id, order_status, quantity를 요청하고 paid 행만 유지하며 주문 ID로 정렬하여 처음 두 행을 반환합니다. 남을 행을 예상해 보세요. 제공된 여섯 주문 중 그 순서에서 먼저 나오는 결제 완료 ID는 o1과 o2입니다.
나중에 확인하고 다시 실행할 수 있도록 SQL을 로컬 파일에 저장합니다. 다음 셸 명령에서 cat > file <<'SQL'은 **히어 도큐먼트(here-document)**를 시작합니다. 끝의 SQL까지 나오는 줄을 문자 그대로 파일에 씁니다. 이 줄들은 셸 명령이 아니라 SQL 텍스트입니다. 구분자 줄을 포함한 블록 전체를 복사하세요.
cat > /home/labex/project/queries/first-query.sql <<'SQL'
USE retail_intro;
SELECT order_id, order_status, quantity
FROM orders
WHERE order_status = 'paid'
ORDER BY order_id
LIMIT 2;
SQL
SQL 안에서 따옴표로 묶인 'paid'는 텍스트 값입니다. =는 각 행의 상태를 그 값과 비교하며 새 상태를 할당하지 않습니다. USE 문 덕분에 파일은 이전 클라이언트 세션에 의존하지 않습니다.
Beeline의 -f 옵션은 로컬 SQL 파일을 읽습니다. 방금 배운 텍스트 형식 옵션으로 파일을 실행하고 출력을 저장합니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/first-query.sql > /home/labex/project/output/first-query.txt
저장한 기록을 읽습니다.
cat /home/labex/project/output/first-query.txt
결과 행은 다음과 같아야 합니다.
o1 paid 2
o2 paid 1
주변에 있는 실행 메시지는 주문 기록이 아닙니다. LIMIT 2는 임의의 두 행을 뜻하지 않습니다. 명시적인 정렬에 따라 조건에 맞는 행 중 무엇이 먼저 나오는지가 결정됩니다. 이제 재사용할 수 있는 쿼리 파일과 팀의 질문에 대한 관찰 가능한 결과가 있습니다.
조건 하나를 바꾼 효과 예상하기
이 단계에서는 상태 조건만 바꾸고 반환되는 행이 예상과 같은지 확인합니다.
결제 완료 주문 쿼리는 그대로 유지합니다. 같은 테이블에 pending 주문 o3이 있으며 수량은 1입니다. 상태 조건을 paid에서 pending으로 바꾸면 최대 두 행을 반환하는 제한에서 몇 행이 나올까요? 제한은 최댓값이므로 답은 한 행입니다.
조건만 바꿔 같은 쿼리를 작성합니다.
cat > /home/labex/project/queries/pending-query.sql <<'SQL'
USE retail_intro;
SELECT order_id, order_status, quantity
FROM orders
WHERE order_status = 'pending'
ORDER BY order_id
LIMIT 2;
SQL
독립적으로 실행합니다.
beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true --showHeader=false --outputformat=tsv2 -f /home/labex/project/queries/pending-query.sql > /home/labex/project/output/pending-query.txt
저장한 결과를 읽습니다.
cat /home/labex/project/output/pending-query.txt
주문 행은 다음 하나뿐이어야 합니다.
o3 pending 1
필터를 바꾸면 테이블에 저장된 기록은 바뀌지 않고 다른 행이 선택됩니다. 이제 같은 기본 쿼리 구조로 두 질문에 답했습니다. 다음에는 준비된 테이블에 의존하는 대신 기존 CSV 파일을 테이블 정의에 연결합니다.
요약
파일에서 테이블을 거쳐 쿼리로 이어지는 작업 흐름 속에서 Hive의 역할을 이해하고, Beeline으로 연결하여 데이터베이스, 테이블과 스키마를 살펴보았습니다. 선택, 필터링, 명시적 정렬과 행 수 제한을 사용하는 재사용 가능한 SQL 파일을 작성하고, 조건 하나의 변화를 예상하고 확인했습니다.
첫 경험을 위해 테이블이 준비되어 있었습니다. 다음 실습에서는 CSV 파일을 자신의 외부 테이블에 연결하고 메타데이터와 실제 파일의 관계를 배웁니다.



