ClickHouse의 저장 프로시저 대안
ClickHouse는 제어 흐름 로직(IF/ELSE, 루프 등)이 포함된 전통적인 저장 프로시저를 지원하지 않습니다.
이는 분석형 데이터베이스인 ClickHouse의 아키텍처를 기반으로 한 의도적인 설계 결정입니다.
분석형 데이터베이스에서는 루프 사용을 권장하지 않습니다. O(n)개의 단순 쿼리를 처리하는 작업은 일반적으로 더 적은 수의 복잡한 쿼리를 처리하는 것보다 느리기 때문입니다.
ClickHouse는 다음과 같은 작업에 최적화되어 있습니다.
- 분석 워크로드 - 대규모 데이터셋에 대한 복잡한 집계
- 배치 처리 - 대용량 데이터를 효율적으로 처리
- 선언형 쿼리 - 데이터를 어떻게 처리할지가 아니라 어떤 데이터를 가져올지 설명하는 SQL 쿼리
사용자 정의 함수(UDFs)
사용자 정의 함수를 사용하면 제어 흐름 없이 재사용 가능한 로직을 캡슐화할 수 있습니다. ClickHouse는 2가지 타입을 지원합니다:람다 기반 UDF
SQL 표현식과 람다 구문을 사용해 함수를 만듭니다:예시에 사용할 샘플 데이터
예시에 사용할 샘플 데이터
- 루프나 복잡한 제어 흐름은 사용할 수 없습니다
- 데이터를 수정할 수 없습니다 (
INSERT/UPDATE/DELETE) - 재귀 함수는 허용되지 않습니다
CREATE FUNCTION에서 확인하십시오.
실행형 UDF
더 복잡한 로직이 필요하면 외부 프로그램을 호출하는 실행형 UDF를 사용합니다:매개변수화된 뷰
매개변수화된 뷰는 데이터셋을 반환하는 함수처럼 작동합니다. 동적 필터링이 필요한 재사용 가능한 쿼리에 적합합니다:예시에 사용할 샘플 데이터
예시에 사용할 샘플 데이터
일반적인 사용 사례
- 동적 날짜 범위 필터링
- 사용자별 데이터 세분화
- 멀티 테넌트 데이터 액세스
- 보고서 템플릿
- 데이터 마스킹
Materialized views
Materialized views는 일반적으로 저장 프로시저에서 처리하는 비용이 큰 집계를 미리 계산하는 데 적합합니다. 기존 데이터베이스에 익숙하다면 materialized view를, 데이터가 원본 테이블에 삽입될 때 이를 자동으로 변환하고 집계하는 INSERT trigger라고 생각하면 됩니다:갱신 가능 materialized view
야간 저장 프로시저와 같은 예약된 일괄 처리 작업에는:외부 오케스트레이션
복잡한 비즈니스 로직, ETL 워크플로, 또는 여러 단계로 이루어진 프로세스는 언제든지 언어 클라이언트를 사용해 ClickHouse 외부에서 구현할 수 있습니다.애플리케이션 코드 사용
다음은 MySQL 저장 프로시저를 ClickHouse에서 애플리케이션 코드로 구현하는 방식을 나란히 비교한 것입니다:- MySQL 저장 프로시저
- ClickHouse용 애플리케이션 코드
주요 차이점
- 제어 흐름 - MySQL 저장 프로시저는
IF/ELSE,WHILE루프를 사용합니다. ClickHouse에서는 이 로직을 애플리케이션 코드(Python, Java 등)에서 구현합니다 - 트랜잭션 - MySQL은 ACID 트랜잭션을 위해
BEGIN/COMMIT/ROLLBACK를 지원합니다. ClickHouse는 트랜잭션 업데이트가 아니라 추가 전용 워크로드에 최적화된 분석형 데이터베이스입니다 - 업데이트 - MySQL은
UPDATESQL 문을 사용합니다. ClickHouse는 변경 가능한 데이터를 처리할 때 ReplacingMergeTree 또는 CollapsingMergeTree와 함께INSERT를 사용하는 방식을 선호합니다 - 변수와 상태 - MySQL 저장 프로시저는 변수(
DECLARE v_discount)를 선언할 수 있습니다. ClickHouse에서는 상태를 애플리케이션 코드에서 관리합니다 - 오류 처리 - MySQL은
SIGNAL및 예외 처리기를 지원합니다. 애플리케이션 코드에서는 사용하는 언어의 네이티브 오류 처리(try/catch)를 사용합니다
워크플로 오케스트레이션 도구 사용
- Apache Airflow - ClickHouse 쿼리로 구성된 복잡한 DAG의 실행 일정을 관리하고 모니터링합니다
- dbt - SQL 기반 워크플로를 사용해 데이터를 변환합니다
- Prefect/Dagster - 최신 Python 기반 오케스트레이션 도구입니다
- Custom schedulers - Cron 작업, Kubernetes CronJobs 등
- 완전한 프로그래밍 언어 기능 활용
- 더 뛰어난 오류 처리 및 재시도 로직
- 외부 시스템(API, 다른 데이터베이스)과의 통합
- 버전 관리 및 테스트
- 모니터링 및 알림
- 더 유연한 일정 관리
ClickHouse에서 prepared statements의 대안
ClickHouse는 RDBMS의 전통적인 “prepared statements”를 지원하지는 않지만, 같은 목적을 하는 쿼리 매개변수를 제공합니다. 즉, SQL 인젝션을 방지하는 안전한 매개변수화 쿼리를 사용할 수 있습니다.구문
쿼리 매개변수는 다음 두 가지 방법으로 정의할 수 있습니다.메서드 1: SET 사용
예시 테이블과 데이터
예시 테이블과 데이터
방법 2: CLI 매개변수 사용
매개변수 구문
매개변수는 다음 구문을 사용해 참조합니다:{parameter_name: DataType}
parameter_name- 매개변수의 이름(param_접두사 제외)DataType- 매개변수를 변환할 ClickHouse 데이터 타입
데이터 타입 예시
예시에 사용할 테이블 및 샘플 데이터
예시에 사용할 테이블 및 샘플 데이터
- 문자열 & 숫자
- 날짜 & 시간
- 배열
- 맵
- 식별자
language clients에서 쿼리 매개변수를 사용하는 방법은 사용하려는 언어 클라이언트의 문서를 참조하십시오.
쿼리 매개변수의 제한 사항
쿼리 매개변수는 범용 텍스트 치환이 아닙니다. 다음과 같은 명확한 제한이 있습니다.- 주로 SELECT SQL 문에서 사용하도록 설계되었습니다 - SELECT 쿼리에서 가장 잘 지원됩니다
- 식별자 또는 리터럴로만 사용할 수 있습니다 - 임의의 SQL 구문 조각을 대체할 수는 없습니다
- DDL 지원은 제한적입니다 -
CREATE TABLE에서는 지원되지만ALTER TABLE에서는 지원되지 않습니다
보안 모범 사례
사용자 입력에는 항상 쿼리 매개변수를 사용하세요:MySQL 프로토콜 prepared statements
ClickHouse의 MySQL 인터페이스에는 prepared statements(COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_CLOSE)에 대한 최소한의 지원이 포함되어 있습니다. 이는 주로 쿼리를 prepared statements로 감싸는 Tableau Online과 같은 도구의 연결을 가능하게 하기 위한 것입니다.
주요 제한 사항:
- 매개변수 바인딩은 지원되지 않습니다 - 바인딩된 매개변수와 함께
?플레이스홀더를 사용할 수 없습니다 - 쿼리는 저장되지만
PREPARE시점에는 파싱되지 않습니다 - 구현은 최소한으로만 제공되며, 특정 BI 도구와의 호환성을 위해 설계되었습니다
요약
저장 프로시저의 ClickHouse 대안
쿼리 매개변수 사용
쿼리 매개변수는 다음과 같은 용도로 사용할 수 있습니다.- SQL 인젝션 방지
- 타입 안전성이 있는 매개변수화된 쿼리
- 애플리케이션에서의 동적 필터링
- 재사용 가능한 쿼리 템플릿
관련 문서
CREATE FUNCTION- 사용자 정의 함수CREATE VIEW- 매개변수화된 뷰와 materialized view를 비롯한 뷰- SQL 구문 - 쿼리 매개변수 - 쿼리 매개변수의 전체 구문
- 연쇄 materialized view - 고급 materialized view 패턴
- 실행형 UDFs - 외부 함수 실행