Skip to main content
이 엔진은 SQLite로 데이터를 가져오고 내보낼 수 있으며, ClickHouse에서 SQLite 테이블에 직접 쿼리할 수도 있습니다.

테이블 생성

엔진 매개변수
  • db_path — 데이터베이스가 저장된 SQLite 파일의 경로입니다.
  • table — SQLite 데이터베이스 내 테이블 이름이거나, SQLite에 그대로 전달되는 쿼리입니다(테이블 이름 대신 쿌리 전달 참조).

테이블 이름 대신 쿼리 전달하기

table 인수에는 테이블 이름 대신 SQLite에 그대로 전달되는 SELECT 쿼리를 지정할 수 있습니다. 테이블 구조는 쿼리 결과로부터 추론됩니다. SQLite는 테이블의 컬럼을 직접 가리키는 결과 컬럼에 대해서만 선언된 타입을 보고하며, 표현식, 리터럴, 집계에 대해서는 아무것도 보고하지 않습니다. String에 매핑되는 선언된 타입(타입 매핑 참조)은 그대로 사용됩니다. 선언된 타입이 없는 컬럼은 쿼리 결과의 첫 번째 행에 있는 값의 저장 클래스(storage class)에 따라 타입이 결정됩니다. INTEGER 값은 Int64, REAL 값은 Float64가 되며, 그 밖의 값(TEXT, BLOB, NULL)이나 결과가 비어 있는 경우에는 String이 됩니다. 숫자형으로 선언된 타입도 첫 번째 행의 값과 대조하여 확인합니다. SQLite는 복합 SELECT에 대해서도 선언된 타입을 보고하는데, 행은 모든 분기에서 가져오는 반면 선언된 타입은 그중 한 분기에서만 가져오기 때문입니다. 값의 저장 클래스가 선언된 타입과 일치하면(정수 타입은 INTEGER, 부동 소수점 타입은 INTEGER 또는 REAL) 해당 타입이 유지됩니다. 값이 NULL이거나 결과가 비어 있어도 선언된 타입과 모순되는 타입 정보가 없으므로 해당 타입이 유지됩니다. 그 외에는 선언되지 않은 컬럼과 마찬가지로 저장 클래스에 따라 타입이 결정됩니다. 따라서 추론된 타입은 넓어질 수는 있어도 좁아지는 일은 없습니다. 이러한 컬럼의 타입을 추론하는 과정에서 SQLite의 쿼리가 실행됩니다. 단, 첫 번째 행이 나머지 행을 대표하지는 않습니다. SQLite는 행마다 다른 저장 클래스를 반환할 수 있으므로(예: CASE WHEN id = 1 THEN 1 ELSE 1.5 END), 쿼리 기반 읽기는 선언된 타입이 없는 컬럼뿐 아니라 숫자형 타입으로 읽는 모든 컬럼에 대해 실패 시 차단(fail-closed) 방식으로 동작합니다. 저장 클래스가 해당 타입과 일치하지 않거나 해당 타입으로 정확히 표현할 수 없는 값(예: UInt8 컬럼에 있는 값이 300인 INTEGER 셀, Float32 컬럼에 있는 값이 16777217인 REAL 셀)은 암묵적으로 변환되지 않으며, 읽기가 실패합니다. 여러 저장 클래스의 값이 섞인 컬럼을 읽으려면 해당 컬럼을 String으로 선언하거나 SQLite 쿼리에서 텍스트로 캐스팅하십시오. 추론된 컬럼은 모두 Nullable입니다. 쿼리는 서브쿼리로 작성하거나 query 함수로 감싸서 작성할 수 있습니다:
쿼리 전달은 버전 26.7부터 지원됩니다. ClickHouse는 쿼리를 SQLite로 보내기 전에 SELECT ... FROM (<query>) 형태로 감싸므로, 쿼리 끝에 세미콜론을 붙이면 안 됩니다. 이러한 테이블은 읽기 전용이므로 INSERT를 수행할 수 없습니다. sqlite 테이블 함수에서도 동일한 구문을 지원합니다.
서브쿼리 형식인 (SELECT ...)는 ClickHouse에서 파싱된 뒤 다시 직렬화되어 SQLite로 전송됩니다. 따라서 유효한 ClickHouse SQL이어야 합니다. ClickHouse가 파싱하지 못하는 SQLite 전용 구문을 전달하려면 query('...') 형식을 사용하십시오. 이 형식의 텍스트는 그대로 SQLite로 전송됩니다.상위 ClickHouse 쿼리의 WHERE, LIMIT, 집계 등은 전달된 쿼리로 푸시다운되지 않으며, 전체 쿼리 결과를 가져온 후 ClickHouse에서 적용됩니다. SQLite에서 읽을 데이터를 제한하려면 전달된 쿼리 안에 filter를 넣으십시오. external_table_strict_query = 1을 사용하면 전달된 쿼리로 푸시다운할 수 없는 이 테이블의 컬럼에 대한 상위 filter는 로컬에서 적용되는 대신 예외와 함께 거부됩니다. 검사는 최상위 WHERE 프레디케이트와 최상위 AND의 각 결합항을 대상으로 합니다. 이 테이블의 컬럼에 대한 PREWHERE는 이 설정의 대상이 아닙니다. 이 테이블 엔진은 PREWHERE를 지원하지 않으므로, 이러한 쿼리는 설정과 관계없이 ILLEGAL_PREWHERE와 함께 거부됩니다. 검사는 filter를 푸시다운할 수 있는 경우에만 실행됩니다. 즉, 이 테이블이 쿼리의 유일한 테이블인 경우, INNER JOIN의 양쪽, 또는 외부 조인의 보존 측(LEFT JOIN의 왼쪽, RIGHT JOIN의 오른쪽)에서만 실행됩니다. LEFT/RIGHT JOIN의 비보존 측과 FULL JOIN의 양쪽에서는 아무것도 푸시다운되거나 검사되지 않으므로, 엄격 모드에서도 이 테이블의 컬럼에 대한 filter는 조인 후 로컬에서 적용됩니다. 검사가 실행되는 위치에서 주변 쿼리에 조인된 다른 테이블을 참조하는 프레디케이트는 조인된 측만 참조하든, 하나의 AND가 아닌 표현식(예: OR) 내부에서 이 테이블과 함께 참조하든 푸시다운되지 않으며 검사에서 제외됩니다. 이러한 프레디케이트는 일반적인 ClickHouse 평가 시점(WHERE는 조인 후, PREWHERE는 조인 전)을 유지하며 거부되지 않습니다.

데이터 타입 지원

테이블 정의에서 ClickHouse 컬럼 타입을 명시적으로 지정하면, SQLite TEXT 컬럼에서 다음 ClickHouse 타입으로 파싱할 수 있습니다: 기본 타입 매핑은 SQLite 데이터베이스 엔진 문서를 참조하십시오. SQLite의 NULL 값을 Nullable이 아닌 타입으로 명시적으로 선언된 ClickHouse 컬럼으로 읽으면 CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN 예외가 발생합니다. NULL 값을 읽으려면 컬럼을 Nullable로 선언하십시오. 추론된 스키마는 SQLite 메타데이터를 따르므로, NOT NULL로 선언되지 않은 컬럼은 Nullable이 됩니다.

사용 예시

다음은 SQLite 테이블을 생성하는 쿼리입니다:
테이블에서 데이터를 반환합니다:
관련 항목