Hive 함수: 내장 함수 및 사용자 정의 함수(UDF) 예제

⚡ 스마트 요약

Hive 함수는 크게 두 그룹으로 나뉩니다. 하나는 Hive 엔진에 내장된 함수로, 컬렉션, 날짜, 수학, 조건문, 문자열 및 기타 작업을 처리합니다. 다른 하나는 사용자가 직접 작성한 함수입니다. Java Hive는 로직을 제공하지 않습니다.

  • 📚 내장된 6가지 패밀리: HiveQL에서는 컬렉션, 날짜, 수학, 조건부, 문자열 및 기타 함수를 직접 호출할 수 있습니다.
  • 🧾 서명은 중요합니다: 모든 함수는 고정된 인자 목록과 문서화된 반환 타입을 가지고 있으므로, 반환 타입에 따라 사용 가능 위치가 결정됩니다.
  • 🧩 UDF는 부족한 부분을 채워줍니다: 내장 함수가 없는 경우, Java org.apache.hadoop.hive.ql.exec.UDF를 확장하는 클래스가 누락된 작업을 제공합니다.
  • 🔢 사용자 정의 함수의 세 가지 형태: UDF는 행 단위로 결과를 반환하고, UDAF는 여러 행을 하나로 축소하며, UDTF는 하나의 행을 여러 행으로 확장합니다.
  • 🛠️ 등록은 두 단계로 진행됩니다. `ADD JAR`는 코드를 클래스패스에 추가하고, `CREATE TEMPORARY FUNCTION`은 클래스에 이름을 지정합니다.
  • ♻️ 재사용이 핵심입니다. 테스트를 거친 UDF(사용자 정의 함수) 중 하나(예: 어간 추출기)는 매번 다시 작성할 필요 없이 모든 쿼리에서 호출할 수 있습니다.

Hive 함수: 내장 함수 및 사용자 정의 함수

함수는 테이블 열 이름의 피연산자에 대해 수학적, 산술적, 논리적 및 관계형 연산과 같은 작업을 수행하기 위한 특정 목적을 위해 만들어집니다.

내장 함수

이는 Hive에서 이미 사용할 수 있는 기능입니다. 먼저 애플리케이션 요구 사항을 확인한 다음 애플리케이션에서 이러한 내장 기능을 사용할 수 있습니다. 우리는 애플리케이션에서 이러한 함수를 직접 호출할 수 있습니다.

구문과 유형은 다음 섹션에서 설명됩니다.

Hive에 내장된 함수의 종류:

  • 수집 기능
  • 날짜 함수
  • 수학 함수
  • 조건부 함수
  • 문자열 함수
  • 기타 기능

아래에서는 6개 패밀리 각각에 대한 함수 시그니처와 반환 타입을 설명합니다.

수집 기능

이 함수들은 컬렉션에 사용됩니다. 컬렉션이란 그룹을 의미합니다.ping 이 함수들은 여러 요소를 포함하며, 함수 이름에 명시된 반환 유형에 따라 단일 요소 또는 요소 배열을 반환합니다.

반환 유형 기능 명 기술설명
INT 크기(지도 ) 맵 유형에 포함된 구성 요소의 수를 가져와서 표시합니다.
INT 크기(배열 ) 배열 타입의 요소 개수를 가져와서 반환합니다.
정렬 맵 키(맵) ) 이 함수는 입력 맵의 키를 포함하는 배열을 가져와 반환합니다. 이 배열은 순서가 지정되어 있지 않습니다.
정렬 맵_값(맵 ) 이 함수는 입력 맵의 값을 담은 배열을 가져와 반환합니다. 이 배열은 순서가 지정되어 있지 않습니다.
정렬 배열 정렬(Array) ) 입력 배열을 요소들의 오름차순으로 정렬하여 반환합니다.
부울 array_contains(Array , 값) 배열에 두 번째 인수로 전달된 값이 포함되어 있으면 TRUE를 반환합니다.

날짜 함수

이것들은 날짜 조작 및 날짜 유형을 한 유형에서 다른 유형으로 변환하는 데 사용됩니다.

기능 명 반환 유형 기술설명
유닉스 타임스탬프() BigInt 우리는 현재를 얻을 것입니다 유닉스 타임스탬프는 초 단위입니다. 이 값은 전체 쿼리 동안 고정되어 있지 않습니다.
to_date(문자열 타임스탬프) 데이터 이 함수는 타임스탬프 문자열에서 날짜 부분만 가져와서 반환합니다.
연도(문자열 날짜) INT 날짜 또는 타임스탬프 문자열의 연도 부분을 가져와서 제공합니다.
분기(날짜/타임스탬프/문자열) INT 1~4 범위의 날짜, 타임스탬프 또는 문자열에 대한 연도의 분기를 가져와서 제공합니다.
월(문자열 날짜) INT 날짜 또는 타임스탬프 문자열의 월 부분을 제공합니다.
시간(문자열 날짜) INT 해당 함수는 타임스탬프의 시간을 가져와서 표시합니다.
분(문자열 날짜) INT 해당 함수는 타임스탬프의 분을 가져와서 표시합니다.
date_sub(문자열 시작 날짜, 정수 일수) 데이터 하위 항목의 결과를 가져와서 표시합니다.trac시작일로부터 며칠 후
현재 날짜 데이터 쿼리 평가 시작 시 현재 날짜를 가져와서 표시합니다.
마지막 날짜(문자열 날짜) 해당 날짜가 속한 달의 마지막 날짜를 가져와서 보여줍니다.
trunc(문자열 날짜, 문자열 형식) 지정된 형식에 맞춰 날짜를 잘라내어 표시합니다. 지원되는 형식 : 월/월/MM, 연도/YYYY/YY.

수학 함수

이 함수들은 수학 연산에 사용됩니다. 사용자 정의 함수(UDF)를 직접 만드는 대신, Hive에는 몇 가지 내장 수학 함수가 있습니다.

기능 명 반환 유형 기술설명
라운드(더블 X) 더블 이 함수는 X의 반올림된 BIGINT 값을 가져와 반환합니다.
라운드(DOUBLE X, INT d) 더블 이 함수는 X 값을 소수점 d자리까지 반올림하여 반환합니다.
라운드(더블 X) 더블 이 함수는 HALF_EVEN 반올림 모드(일명 은행가 반올림)를 사용하여 X의 반올림된 BIGINT 값을 가져와 반환합니다.
바닥(더블X) 빅인트 이 함수는 X 값과 같거나 그보다 작은 최대 BIGINT 값을 가져와 반환합니다.
천장(더블 a), 천장(더블 a) 빅인트 이 함수는 지정된 값보다 크거나 같은 최소 BIGINT 값을 가져와 반환합니다.
rand(), rand(INT 시드) 더블 이 함수는 0에서 1 사이의 균일 분포를 따르는 난수를 생성하여 반환합니다. 시드 값을 제공하면 생성된 난수 시퀀스를 반복적으로 사용할 수 있습니다.

조건부 함수

이 함수들은 조건부 값 검사에 사용됩니다.

기능 명 반환 유형 기술설명
if(부울 테스트조건, T valueTrue, T valueFalseOrNull) T 테스트 조건이 참이면 true를 반환하고, 그렇지 않으면 false 또는 null을 반환합니다.
isnull(X) 부울 X가 NULL이면 true를, 그렇지 않으면 false를 반환합니다.
isnotnull(X) 부울 X가 NULL이 아니면 true를, 그렇지 않으면 false를 반환합니다.
nvl(T 값, T 기본값) T 값이 NULL이면 default_value를 반환하고, 그렇지 않으면 value를 반환합니다.

문자열 함수

문자열 조작 및 문자열 연산은 다음 함수들을 통해 처리됩니다.

기능 명 반환 유형 기술설명
역(문자열 X) X의 역방향 문자열을 제공합니다.
rpad(문자열 str, int 길이, 문자열 패드) 이 함수는 `str` 값을 가져와서 `pad`를 추가하여 총 길이를 `length`로 조정합니다.
rtrim(문자열 X) 이 함수는 X의 끝(오른쪽)에서 공백을 제거한 문자열을 가져와 반환합니다.
예를 들어, rtrim(' 결과 ') 결과는 ' 결과'입니다.
공간(INT n) 이 함수는 n개의 공백으로 이루어진 문자열을 가져와 반환합니다.
분할(STRING str, STRING pat) 정렬 pat를 기준으로 str을 분할합니다(pat는 정규 표현식입니다).
str_to_map(text[, delimiter1, delimiter2]) 지도 이 함수는 두 개의 구분자를 사용하여 텍스트를 키-값 쌍으로 나눕니다. 구분자 1은 쌍을 분리하고, 구분자 2는 각 쌍을 다시 분리합니다.

기타 기능

내장 함수 중 일부는 위의 어떤 계열에도 속하지 않습니다. 이러한 함수에는 해싱, 세션 정보 및 임의의 함수 호출이 포함됩니다. Java 방법.

기능 명 반환 유형 기술설명
hash(a1[, a2…]) INT 인수들의 해시값을 반환합니다.
현재 사용자() 구성된 인증 관리자에서 현재 사용자 이름을 반환합니다.
현재 데이터베이스() 현재 데이터베이스의 이름을 반환합니다.
md5(문자열/바이너리) MD5 128비트 체크섬을 32자리 16진수 문자열로 반환하거나, 인수가 NULL인 경우 NULL을 반환합니다.
sha1(문자열/바이너리) 인수의 SHA-1 다이제스트를 16진수 문자열로 반환합니다.
crc32(문자열/바이너리) BigInt 문자열 또는 이진 인수의 순환 중복 검사(CRC) 값을 반환합니다.
버전() Hive 버전을 빌드 번호와 빌드 해시 값으로 반환합니다.
reflect(클래스, 메서드[, arg1…]) 따라 다릅니다 전화하다 Java 리플렉션을 사용하여 인자 시그니처를 일치시켜 메서드를 찾습니다. java_method()는 동의어입니다.

UDF(사용자 정의 함수)

Hive에서는 사용자가 특정 클라이언트 요구 사항을 충족하기 위해 사용자 정의 함수(UDF)를 정의할 수 있습니다. 사용자 정의 함수는 다음과 같이 작성됩니다. Java 특정 모듈의 경우.

일부 사용자 정의 함수(UDF)는 애플리케이션 프레임워크에서 코드 재사용성을 위해 특별히 설계되었습니다. 개발자는 이러한 함수를 다음과 같은 방식으로 작성합니다. Java 그리고 이러한 UDF를 Hive와 통합합니다.

쿼리 실행 중에 개발자는 코드를 직접 사용할 수 있으며, UDF(사용자 정의 함수)는 사용자가 정의한 작업에 따라 출력을 반환합니다. 이는 코딩 및 실행 측면에서 높은 성능을 제공합니다.

예를 들어, 문자열 어간 추출을 위해 Hive에는 미리 정의된 함수가 없습니다. 따라서 어간 추출을 위한 사용자 정의 함수(UDF)를 직접 작성할 수 있습니다. Java스템 기능이 필요한 곳이라면 어디든 Hive에서 이 스템 UDF를 직접 호출할 수 있습니다.

여기서 어간 추출이란 어근에서 파생된 단어를 만드는 것을 의미합니다. 어간 추출 알고리즘은 "wishing", "wished", "wishes"라는 단어를 어근 "wish"로 줄여줍니다. 이러한 기능을 수행하기 위해 사용자 정의 함수(UDF)를 작성할 수 있습니다. Java 그리고 그것을 통합 하이브.

사용 사례에 따라 UDF는 서로 다른 수의 입력값과 출력값을 받아들이고 생성하도록 작성될 수 있습니다.

일반적인 유형의 사용자 정의 함수(UDF)는 단일 입력값을 받아 단일 출력값을 생성합니다. UDF가 쿼리에서 사용되는 경우, 결과 데이터 세트의 각 행에 대해 한 번씩 호출됩니다.

반대로, 함수는 여러 값을 입력으로 받아 하나의 출력 값을 반환할 수도 있습니다. 이러한 차이점이 다음에 설명할 세 가지 사용자 정의 함수 유형을 구분하는 기준이 됩니다.

Hive에서 UDF, UDAF, UDTF 비교

Hive의 사용자 정의 함수는 입력 행 수와 출력 행 수에 따라 그룹화됩니다. 사용자 정의 함수가 컴파일되지 않거나 테이블이 필요한 위치에 단일 행을 반환하는 가장 일반적인 이유는 잘못된 데이터 유형을 선택했기 때문입니다.

타입 행 입력 → 행 출력 확장할 클래스 내장 예제
UDF 한 줄 → 한 줄 org.apache.hadoop.hive.ql.exec.UDF 길이(), 반올림(), 역순()
UDAF 여러 행 → 한 행 org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver count(), min(), max()
UDTF 한 줄 → 여러 줄 org.apache.hadoop.hive.ql.udf.generic.GenericUDTF explode(), json_tuple(), parse_url_tuple()

다음 표에서 두 가지 실용적인 규칙을 도출할 수 있습니다.

  • UDAF는 각 그룹을 하나의 행으로 축소하기 때문에 거의 항상 GROUP BY 절과 함께 사용됩니다.
  • UDTF는 동일한 SELECT 목록에서 다른 열과 함께 선택할 수 없으므로 일반적으로 LATERAL VIEW와 함께 사용됩니다.

행 수준 작업을 위한 두 번째 기본 클래스인 GenericUDF도 있으며, 이 클래스는 배열, 맵, 구조체와 같은 복합 유형과 가변 개수의 인수를 허용합니다.

Hive에서 UDF를 작성하고 등록하는 방법

위에서 설명한 줄기 예시는 네 단계만으로 실제 함수로 구현할 수 있습니다. 그 이상은 없습니다. Java 컴파일러와 실행 중인 Hive 세션이 필요합니다.

단계 1) 쓰기 Java UDF를 상속하고 public evaluate() 메서드를 구현하는 클래스입니다. Hive는 행당 한 번씩 evaluate() 메서드를 호출하므로, 이 메서드는 NULL 입력을 처리해야 합니다.

package com.guru99.hive.udf;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

public final class Stem extends UDF {

    public Text evaluate(final Text input) {
        if (input == null) {
            return null;
        }
        String word = input.toString().toLowerCase();
        if (word.endsWith("ing")) {
            word = word.substring(0, word.length() - 3);
        } else if (word.endsWith("ed") || word.endsWith("es")) {
            word = word.substring(0, word.length() - 2);
        }
        return new Text(word);
    }
}

단계 2) 클래스를 컴파일하고 해당 클래스가 의존하는 모든 클래스와 함께 hive-udf-1.0.jar과 같은 JAR 파일로 패키징합니다.

단계 3) Hive 클래스패스에 JAR 파일을 추가하고 함수 이름을 클래스에 바인딩하세요. 임시 함수는 현재 세션 동안만 유지됩니다.

ADD JAR /home/hduser/hive-udf-1.0.jar;

CREATE TEMPORARY FUNCTION stem AS 'com.guru99.hive.udf.Stem';

단계 4) 새 함수를 내장 함수처럼 정확히 호출하세요. "wishing", "wished", "wishes"라는 단어에 적용하면 이 클래스는 세 가지 경우 모두 "wish"를 반환합니다.

SELECT word, stem(word) FROM words;

모든 세션과 모든 사용자가 해당 기능을 사용할 수 있도록 하려면 데이터베이스에 영구적으로 등록하십시오. JAR 파일은 클러스터 전체가 읽을 수 있는 경로에 있어야 하며, 일반적으로 HDFS에 등록하는 것이 좋습니다.

CREATE FUNCTION default.stem AS 'com.guru99.hive.udf.Stem'
USING JAR '/user/hive/udfs/hive-udf-1.0.jar';

하나의 클래스에 여러 개의 evaluate() 메서드가 선언될 수 있습니다. Hive는 함수 호출 시 인자 시그니처를 비교하여 일치하는 함수를 찾습니다. 따라서 하나의 함수가 문자열과 정수를 모두 인자로 받을 수 있습니다.

자주 묻는 질문

`SHOW FUNCTIONS`는 사용자 정의 함수를 포함하여 등록된 모든 함수 이름을 나열합니다. `DESCRIBE FUNCTION name`은 한 줄짜리 함수 시그니처를 출력하고, `DESCRIBE FUNCTION EXTENDED name`은 구현 클래스에서 제공하는 경우 사용 예제를 추가합니다.

거의 대부분 이름이나 범위 문제입니다. AS 뒤에 오는 문자열은 정규화된 클래스 이름이어야 하며, ADD JAR 명령은 해당 명령을 실행한 세션에만 적용됩니다. 다시 연결하면 JAR 파일과 임시 함수가 모두 삭제됩니다.

함수가 배열, 맵 또는 구조체와 같은 복잡한 유형, 가변 개수의 인수를 받거나 인수 유형을 자체적으로 검증해야 하는 경우 GenericUDF를 사용하십시오. 간단한 UDF 클래스는 리플렉션을 통해 유형을 해석하며 기본형 Writable만 처리합니다.

진정한 UDF는 JVM에서 실행되어야 합니다. 다른 언어의 경우, 하이브 TRANSFORM 절을 사용하면 각 행을 외부 스크립트를 통해 스트리밍할 수 있습니다. Python 표준 입력 및 출력을 통한 방식입니다. 속도는 느리지만 오류를 방지할 수 있습니다. Java 전적으로.

가능합니다. evaluate() 함수는 행마다 한 번씩 실행되므로, 비용이 많이 드는 로직은 행 수만큼 반복되고, 메서드 내부에서의 객체 할당은 가비지 컬렉션에 부담을 줍니다. 내장 함수가 있다면 내장 함수를 사용하는 것이 좋고, evaluate() 함수는 I/O 작업을 최소화해야 합니다.

아니요. 함수 이름은 대소문자를 구분하지 않으므로 ROUND(), Round(), round()는 모두 같은 함수입니다. Java AS 절의 클래스 이름은 별개의 문제이며, 패키지를 포함하여 컴파일된 클래스와 정확히 일치해야 합니다.

머신 러닝 기반 도구는 일반 언어로 작성된 설명을 후보 시그니처에 매핑하고, 반환 유형이 대상 열에 맞지 않을 경우 경고를 표시합니다. 생성된 이름이 다른 SQL 방언에 속하는 경우가 있으므로, 제안된 시그니처를 문서화된 시그니처와 비교하여 확인하십시오.

이 함수는 작업을 설명하는 주석으로부터 클래스 선언, 임포트 및 evaluate() 메서드와 같은 사용 가능한 뼈대를 생성합니다. null 처리, 쓰기 가능한 유형 및 패키징 단계는 여전히 검토가 필요하며, 실제 행을 사용하여 함수를 테스트해야 합니다.

이 게시물을 요약하면 다음과 같습니다.