Hive-튜토리얼, 테이블 조작

Hive 정의

하이브는 query langunage인 SQL 을 통해 대규모 데이터에서 쿼리를 수행할 수 있게한다.

하이브는 크게 3가지 메인 기능이 있다.

  1. data summarization
  2. query
  3. analaysis

이를 통해 비즈니스 인사이트를 제공할 수 있다.

또한, 하이브는 HiveQL 이라는 SQL와 유사한 언어를 통해 OLAP (Online Analytic Processing) 기능을 포함하는 SQL 의미의 다양한 집합, sub-query, 공통 테이블 표현 등을 제공한다.

하이브 사용자는 SQL 쿼리를 수행하는 엔진을 Apache MapReduce, Apache Tez, Apache Spark에서 선택할 수 있다.

하이브의 특징을 아래와 같다.

  1. 익숙함

    SQL 기반의 언어를 제공하기 때문에, 개발자가 아닌 비전문가들도 쉽게 데이터를 조작할 수 있다.

  2. 빠르다

    대규모 데이터를 빠르게 처리한다.

  3. 확장성

    하둡 기반으로 동작하기 때문에 확장성에 좋다.

Hive 동작

하이브의 테이블은 관계형 데이터 베이스의 테이블과 유사하다.

각 테이블은 HDFS 디렉토리와 대응된다.

또한, 각 테이블들은 파티션으로 분할될 수 있고, 파이션 내 데이터들은 버킷이라는 단위로 더 세분화 되어 쪼개질 수 있다.

하이브는 아래 프로젝트를 구성한다.

  1. HCatalog

    하이브의 컴포넌트중 하나로, 이는 테이블로 되어있으며, 저장 관리를 해준다.

    하둡 클러스터 내 데이터에 대한 메타데이터 (스키마 정보)와 파일 경로의 집합을 가지고 있다.

    또한, MapReduce, Pig, Tez와 같은 데이터 처리 도구들을 위해 공유될 수 있다.

HiveQL (DDL)

HiveQL은 하이브 쿼리 언어로 널리 사용 중인 SQL 언어와 마찬가지로 ANSI SQL 표준의 어떠한 버전도 완벽하게 따르지는 않는다.

즉, MySQL에서 사용하는 언어와 가장 가까울수는 있어도 모든 기능 제공을 하진 않는다. (로우 레벨의 삽입, 변경, 삭제는 지원이 안되며, 트랜잭션 또한 지원하지 않는다.)

허나 하둡이 지원하는 범위 안에서 보다 나은 성능을 위해 확장할 수 있는 기능을 제공하며, 사용자가 정의한 확장과 외부 프로그램을 하이브와 연동할 수 있다.

데이터 베이스 생성

하이브의 데이터 베이스는 단지 테이블의 카탈로그 또는 네임스페이스로, 많은 사용자들이 이용할 때 테이블명의 충돌을 막기 위한 방법이다.

또한 데이터베이스 테이블을 논리 그룹으로 구성하는데 사용한다.

하이브는 각 데이터베이스마다 별도의 디렉토리를 생성하고 테이블을 그 하위 디렉토리 안에 저장한다.

hive> CREATE DATABASE test

test database생성

hive> CREATE DATABASE if not exists test

test database이 없다면 생성. 이는 test table이 이미 있더라도 에러가 발생하지 않기 위함.

hive> show databases

database 조회

hive> show databases like 'h.*'

h이름을 가진 database 조회

hive> create database test
    > location '/directory'

test database의 디렉토리 위치를 /directory로 변경

hive> use test;

test database 사용

hive> drop database if exists test

test database 삭제

hive> drop database if exists test CASCADE

test database에 테이블이 있을 경우에도 삭제 (기본은 삭제를 허용하지 않음)

테이블 생성

create table if not exists test.test_table (
  id	INT COMMENT 'person id'
  name	StRING COMMENT 'person name'
)
TBLPROPERTIES ('creator'='me', 'created_at'='2019-01-01')
LOCATION '/directory'

test database에 test_table을 생성한다.

if not exists를 통해 테이블이 존재하더라도 하이브는 에러를 내지 않고 넘어간다.

TBLPROPERTIES를 통해 키-값 형태의 문서화를 할 수 있다. (다른 디비와 연동할 때, 다른 디비의 연결 정보와 같은 메타데이터를 넣을 수 있음)

LOCATION을 통해 테이블 데이터의 위치를 지정할 수 있다

create table if not exists test.test_table2 LIKE test.test_table

원하는 스키마만을 복사할 수 있음.

하이브는 크게 두 종류의 테이블이 있다.

매니지드 테이블 (내부 테이블)

하이브가 데이터의 생명 주기를 제어하기 위함.

즉, 하이브는 hive.metastore.warehousr.dir 속성에서 정의한 디렉토리에 하위 디렉토리를 만들어 테이블을 저장한다. 위에서 생성한 테이블이 내부 테이블이다.

허나, 하이브가 데이터를 소유하지 않기를 원할 때, 외부 테이블을 정의하여 하이브가 해당 데이터를 소유하지 않도록 한다.

외부 테이블

위에서 보듯 외부 테이블은 하이브가 테이블의 데이터를 소유하지 않는다.

create external table if not exists test.test_table3 (
 ...
)
LOCATION '/data'

내부 테이블과는 다르게 external이 추가된다.

LOCATION을 통해 외부 데이터가 어디 저장되어 있는지 하이브에게 알려준다.

LOCATION에 있는 데이터는 해당 데이터를 소유하지 않는다.

따라서 테이블을 삭제하면 테이블의 메타데이터만 지워지지만 해당 데이터는 지우지 않는다.

파티셔닝된 매니지드 테이블

데이터 파티셔닝은 수평적으로 부하를 분산하기 위해 자주 사용하는 데이터를 사용자와 물리적으로 가까운 위치에 두는 등의 목적으로 사용한다.

create table test.test_table_partitioned (
...
)
PARTITIONED BY (date TIMESTAMP, hour TIMESTAMP)

Partitioned by를 통해 partition 하고 싶은 filed를 지정할 수 있다.

위는 날짜와 시간 정보로 파티션을 지정한다는 의미이다.

위 처럼 테이블을 생성하면 아래와 같이 하위 디렉토리가 생성된다.

.../test_table_partitioned/date=2019-01-01/hour=01
.../test_table_partitioned/date=2019-01-01/hour=02
.../test_table_partitioned/date=2019-01-01/hour=03
...
.../test_table_partitioned/date=2019-02-01/hour=01
.../test_table_partitioned/date=2019-02-01/hour=02
.../test_table_partitioned/date=2019-02-01/hour=03
...

빠른 쿼리를 위해 데이터 파티셔닝을 이용한다.

내가 원하는 쿼리의 데이터만 조회할 때 디렉토리 한 두개만 살펴보면 조회할 수 있기 때문이다.

물론 모든 날짜의 데이터를 읽고 싶다면 모든 디렉토리를 읽겠지만, 디스크 읽기를 광범위하게 하는 작업은 상대적으로 많지 않는게 좋다.

가장 안전한 방법은 하이브를 제한하여 WHERE문이 없다면 쿼리를 금지할 수 있도록 제한하는 것이 가장 좋다.

파티셔닝된 외부 테이블

외부 테이블도 내부 테이블과 마찬가지로 파티셔닝 할 수 있다.

create external table if not exists test.test_table_partitioned (
...
)
PARTITIONED BY (year INT, month INT, day INT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'

외부 테이블을 생성하고, ALTER TABLE 을 통해 파티션을 추가하여 파티셔닝된 외부 테이블을 만들 수 있다.

ALTER TABLE test.test_table_partitioned ADD PARTITION (year=2019, month=1, day=1)
LOCATION 'hdfs://host/directory/2019/01/01'

주로 HDFS 말고 다른 저장소에 오래된 데이터를 저장하고 있을 때 이러한 파티셔닝된 외부 테이블을 사용하면 유용하다.

테이블 변경

alter table test_table RENAME to test_table_tmp

alter table명령을 통해 테이블의 속성을 바꿀 수 있다. 위는 테이블의 이름을 바꾼다.

위에서 살펴본 파티션을 추가하는 것도 alfter table을 통해 수행한다.

alter table ...
set location 's3://partition/'

호출하는 데이터의 위치를 변경할 수 있다.

그외에 컬럼 추가, 변경 등 다양한 기능들이 존재한다.

테이블 삭제

drop table if exists test.test_table

test_table 테이블을 삭제한다.

Comments