연속 구체화된 뷰 쿼리
Bigtable 테이블의 구체화된 연속 뷰를 만들려면 구체화된 연속 뷰를 정의하는 SQL 쿼리를 실행합니다.
이 문서에서는 구체화된 연속 뷰 SQL 쿼리를 준비하는 데 도움이 되는 개념과 패턴을 설명합니다. 이 문서를 읽기 전에 구체화된 연속 뷰 및 Bigtable용 GoogleSQL을 숙지해야 합니다.
구체화된 연속 뷰는 제한된 SQL 구문을 사용합니다. 다음 패턴은 구체화된 연속 뷰 SQL 쿼리를 빌드하는 방법을 보여줍니다.
SELECT
expression AS alias [, ...]
FROM from_item
[ WHERE bool_expression ]
GROUP BY expression [, ...];
from_item:
{
table_name [ as_alias ]
| field_path
}
as_alias:
[ AS ] alias
연속 구체화된 뷰 SQL 쿼리를 비동기 보조 색인으로 빌드하려면 ORDER BY 절을 사용합니다.
SELECT
expression AS alias [, ...]
FROM from_item
[ WHERE bool_expression ]
ORDER BY expression [, ...];
from_item:
{
table_name [ as_alias ]
| field_path
}
as_alias:
[ AS ] alias
비확정적 함수를 사용하는 SQL 쿼리는 다른 구체화된 연속 뷰 쿼리와 의미상 다릅니다. 자세한 내용은 이 문서의 비확정적 쿼리 섹션을 참고하세요.
쿼리 제한사항
구체화된 연속 뷰를 만드는 데 사용되는 SQL 쿼리에는 다음 규칙이 적용됩니다.
SELECT문이어야 합니다.GROUP BY절 또는 비동기 보조 색인 쿼리의 경우ORDER BY절이 있어야 하지만 둘 다 있을 수는 없습니다.- 지원되는 집계 함수만 사용해야 합니다.
- 그룹당 여러 집계를 포함할 수 있습니다.
지원되는 집계
구체화된 연속 뷰를 정의하는 SQL 쿼리에서 다음 집계 함수를 사용할 수 있습니다.
COUNTSUMMINMAXHLL_COUNT.INITHLL_COUNT.MERGEHLL_COUNT.MERGE_PARTIALANY_VALUEBIT_ANDBIT_ORBIT_XORAVG
SELECT COUNT(*)를 사용하는 경우 다음 예와 같이 row key를 정의해야 합니다.
SELECT
'*' AS _key,
COUNT(*) AS count
FROM
foo
GROUP BY
_key;
지원되지 않는 SQL 기능
다음 SQL 기능은 사용할 수 없습니다.
- Bigtable용 GoogleSQL에서 지원되지 않는 기능
ARRAYARRAY_AGGARRAY_CONCAT_AGGCOUNT_IFCURRENT_TIME및 대부분의 다른 비확정적 함수(예외 포함)DATE,DATETIME을 출력 열로 사용 (TIMESTAMP를 사용하거나 문자열을 저장)- 출력의
DESC정렬 DISTINCT옵션(예:SUM(*DISTINCT* value))LIMIT/OFFSETSELECT *- 창 집계를 만드는
OVER절 STRUCT
GROUP BY 또는 ORDER BY 절을 중첩하거나 맵 열을 만들 수도 없습니다. 추가
제한사항은
제한사항을 참고하세요.
제외된 행 방지
입력 행은 다음과 같은 경우 구체화된 연속 뷰에서 제외됩니다.
- 행에서 1MiB가 넘는 데이터가 선택됩니다. 예를 들어
쿼리가
SELECT apple AS apples , SUM(banana) AS sum_bananas FROM my_table GROUP BY apples인 경우apple및banana열에 1MiB가 넘는 데이터가 포함된 행은 구체화된 연속 뷰에서 제외됩니다. - 행에서 1MiB가 넘는 데이터가 출력됩니다. 이는
SELECT REPEAT(apple, 1000)과 같은 쿼리를 사용하거나 큰 상수를 사용하는 경우 발생할 수 있습니다. - 선택된 데이터보다 10배 넘는 데이터가 출력됩니다.
- 쿼리가 데이터와 일치하지 않습니다. 여기에는 0으로 나누려고 시도하거나, 정수 오버플로가 발생하거나, 모든 row key에서 사용되지 않는 row key 형식을 예상하는 것이 포함됩니다.
제외된 행은 처음 처리될 때 사용자 오류 측정항목을 증가시킵니다. 구체화된 연속 뷰를 모니터링하는 데 도움이 되는 측정항목에 대한 자세한 내용은 측정항목을 참고하세요.
쿼리 세부정보
이 섹션에서는 구체화된 연속 뷰 쿼리와 뷰가 쿼리될 때 결과가 어떻게 표시될 수 있는지 설명합니다. 소스 테이블의 데이터는 입력 이고 구체화된 연속 뷰의 결과 데이터는 출력 입니다. 출력 데이터는 집계되거나 집계되지 않습니다 (정의된 키에 있음).
SELECT 문
select 문은 구체화된 연속 뷰에 사용되는 열과 집계를 구성합니다. 문은 GROUP BY 절을 사용하여 행 간에 집계하거나 ORDER BY 절을 사용하여 비동기 보조 색인을 만들어야 합니다.
SELECT *는 지원되지 않지만 SELECT COUNT(*)는 지원됩니다.
일반적인 SELECT 문과 마찬가지로 그룹화된 데이터 세트당 여러 집계를 포함할 수 있습니다. 그룹화되지 않은 열은 집계 결과여야 합니다.
다음은 SQL의 표준 GROUP BY 집계 쿼리의 예입니다.
SELECT
myfamily["node"] AS node,
myfamily["type"] AS type,
COUNT(clicks) AS clicks_per_key
FROM
mytable
GROUP BY
node,
type
Row key 및 집계되지 않은 데이터
구체화된 연속 뷰의 row key로 _key를 지정할 수 있습니다. 그렇지 않으면 GROUP BY 절의 열이 뷰의 키를 형성합니다.
_key 열로 정의된 row key
구체화된 연속 뷰를 정의할 때 선택적으로 _key 열을 지정할 수 있습니다. (이는 Bigtable 테이블에서 SQL 쿼리를 실행할 때 가져오는 _key
열과 다릅니다.) _key를 지정하는 경우 다음 규칙이 적용됩니다.
_key로 그룹화해야 하며, 선택적으로_timestamp를 제외한 다른 항목으로 그룹화할 수 없습니다. 자세한 내용은 타임스탬프를 참고하세요._key열은BYTES유형이어야 합니다.
_key를 지정하면 row key 형식을 제어할 수 있으므로 SQL 대신 ReadRows로 뷰를 읽으려는 경우 유용합니다. 반면에 정의된 _key가 있는 뷰에 대한 SQL 쿼리는 구조화된 키 열을 반환하는 대신 _key를 명시적으로 디코딩해야 할 수 있습니다.
GROUP BY 또는 ORDER BY 절로 정의된 row key
_key를 지정하지 않으면 SELECT 목록의 집계되지 않은 열이 뷰의 row key가 됩니다. SQL 규칙에서 지원하는 이름을 키 열에 할당할 수 있습니다. ReadRows 요청 대신 SQL을 사용하여 뷰를 쿼리하려는 경우 이 접근 방식을 사용합니다.
SELECT 목록의 집계되지 않은 출력 열은 GROUP
BY 절에 포함되어야 합니다. GROUP BY 절에 열이 작성되는 순서는 데이터가 구체화된 연속 뷰 row key에 저장되는 순서입니다. 예를 들어 GROUP BY a, b, c는 암시적으로 ORDER BY a ASC, b ASC, c
ASC입니다.
GROUP BY 절 대신 ORDER BY 절을 사용하여 비동기 보조 색인을 만드는 경우 ORDER BY 절에 포함된 SELECT 목록의 열이 뷰의 row key가 됩니다. ORDER BY 절에 열이 작성되는 순서는 데이터가 구체화된 연속 뷰 row key에 저장되는 순서입니다. 예를 들어 ORDER BY a, b, c는 a ASC, b ASC, c ASC 순으로 정렬된 row key로 데이터를 저장합니다.
SQL 필터는 오류를 일으킬 수 있는 잠재적인 NULL 또는 기타 잘못된 값을 삭제해야 합니다. NULL 키 열이 포함된 행과 같은 잘못된 행은 결과에서 생략되고 materialized_view/user_errors 측정항목에 집계됩니다. 사용자 오류를 디버그하려면 구체화된 연속 뷰 외부에서 SQL 쿼리를 실행해 보세요.
집계된 데이터
쿼리의 집계 열은 구체화된 연속 뷰에서 데이터를 생성하는 계산을 정의합니다.
집계 열의 별칭은 구체화된 연속 뷰에서 열 한정자로 처리됩니다.
다음 예시를 참조하세요.
SELECT
fam["baz"] AS baz,
SUM(fam["foo"]) AS sum_foo,
SUM(fam["bar"]) AS sum_bar
FROM
TABLE
GROUP BY
baz;
쿼리 출력에는 다음과 같은 특징이 있습니다.
- 각
baz의 출력은baz ASC순서로 별도의 행에 있습니다. - 지정된
baz에foo가 하나 이상 있으면 출력 행의sum_foo는 NULL이 아닌 값입니다. - 지정된
baz에bar가 하나 이상 있으면 출력 행의sum_bar는 NULL이 아닌 값입니다. - 지정된
baz에 두 열의 값이 모두 없으면 결과에서 생략됩니다.
그런 다음 SELECT *로 뷰를 쿼리하면 결과가 다음과 비슷하게 표시됩니다.
| baz | sum_foo | sum_bar |
|---|---|---|
| baz1 | sum_foo1 | sum_bar1 |
| baz2 | sum_foo2 | sum_bar2 |
타임스탬프
구체화된 연속 뷰의 출력 셀의 기본 타임스탬프 는 0 (1970-01-01 00:00:00Z)입니다. 이는 SQL로 쿼리할 때가 아니라 ReadRows로 뷰를 읽을 때 표시됩니다.
출력에서 다른 타임스탬프를 사용하려면 TIMESTAMP 유형의 열을 쿼리의 SELECT 목록에 추가하고 이름을 _timestamp로 지정하면 됩니다.
ReadRows를 사용하여 연속 구체화된 뷰를 쿼리하면 _timestamp가 행의 다른 셀의 타임스탬프가 됩니다.
타임스탬프는 NULL이 아니어야 하고 0보다 크거나 같아야 하며 1,000의 배수 (밀리초 정밀도)여야 합니다. Bigtable은 유닉스 시간 (1970-01-01T00:00:00Z) 이전의 셀 타임스탬프를 지원하지 않습니다.
다음은 집계 데이터를 일별로 재샘플링하는 예입니다. 쿼리는 UNPACK 함수를 사용합니다.
SELECT
_key,
TIMESTAMP_TRUNC(_timestamp, DAY) AS _timestamp,
SUM(sum_family["sum_column"]) AS sum_column,
SUM(sum_family["foo"]) AS second_sum_column
FROM
UNPACK(
SELECT
*
FROM
my_table(with_history => TRUE))
GROUP BY
1,
2
지정된 SUM에 지정된 날짜의 비어 있지 않은 입력이 있으면 출력 행에 잘린 날짜와 일치하는 타임스탬프가 있는 집계 값이 포함됩니다.
SELECT *로 뷰를 쿼리하면 결과가 다음과 비슷하게 표시됩니다.
| _key | _timestamp | sum_column | second_sum_column |
|---|---|---|---|
| 1 | 2024-05-01 00:00:00Z | 23 | 99 |
| 2 | 2024-05-02 00:00:00Z | 45 | 201 |
| 3 | 2024-05-03 00:00:00Z | NULL | 56 |
| 4 | 2024-05-04 00:00:00Z | 8 | NULL |
비확정적 쿼리
구체화된 연속 뷰는 다음과 같은 비확정적 SQL 함수를 지원합니다.
클러스터 속성 함수
CLUSTER_ATTRIBUTE() 함수를 사용하면 구체화된 연속 뷰 쿼리를 실행하는 Bigtable 클러스터에 대한 메타데이터에 프로그래매틱 방식으로 액세스할 수 있습니다. cluster_id 속성은 뷰를 처리하는 클러스터의 문자열 식별자를 반환합니다.
뷰를 단일 클러스터로 격리
구체화된 연속 뷰 계산 및 스토리지를 전용 분석 또는 보고 클러스터와 같은 단일
클러스터로 격리하려면
CLUSTER_ATTRIBUTE('cluster_id')를 클러스터 식별자가 포함된 상수 문자열 리터럴과 비교합니다.
SELECT
metrics['sensor_id'] AS sensor_id,
COUNT(1) AS reading_count
FROM `TABLE_ID`
WHERE CLUSTER_ATTRIBUTE('cluster_id') = 'CLUSTER_ID'
GROUP BY 1
다음을 바꿉니다.
TABLE_ID: Bigtable 테이블의 고유 식별자입니다.CLUSTER_ID: 뷰를 구체화하려는 클러스터의 식별자입니다.
이 쿼리는 인스턴스에서 다음과 같이 동작합니다.
- 지정된 클러스터: 일치하는 클러스터에서
CLUSTER_IDWHERE조건은true로 평가됩니다. Bigtable은 클러스터가 수집 또는 복제한 클러스터와 관계없이 소스 테이블의 모든 데이터를 집계하고 해당 클러스터의 뷰 사본에서 해당 데이터를 구체화합니다. - 기타 클러스터: 인스턴스의 다른 모든 클러스터에서
CLUSTER_ATTRIBUTE('cluster_id')는 각 클러스터 ID로 평가되어WHERE조건을false로 만듭니다. 이러한 클러스터는 구체화된 연속 뷰의 행을 계산하거나 저장하지 않으므로 컴퓨팅 및 스토리지 리소스가 절약됩니다.
클러스터 출처별로 데이터 필터링
애플리케이션이 클러스터 메타데이터를 소스 테이블 행에 쓰는 경우(예: origin_cluster라는 열) 행의 출처 클러스터를 처리 클러스터와 일치시킬 수 있습니다.
SELECT
metrics['sensor_id'] AS sensor_id,
COUNT(1) AS reading_count
FROM `TABLE_ID`
WHERE metrics['origin_cluster'] = CLUSTER_ATTRIBUTE('cluster_id')
GROUP BY 1
이 쿼리에서 metrics['origin_cluster']는 행에 저장된 데이터의 속성인 반면 CLUSTER_ATTRIBUTE('cluster_id')는 뷰를 처리하는 클러스터의 속성입니다. 구체화된 연속 뷰의 각 클러스터 복제본은 저장된 origin_cluster가 해당 클러스터의 ID와 일치하는 행만 집계합니다.
일부 행에 출처 클러스터가 지정되지 않을 수 있는 경우 IF_NULL을 사용하여 대체 클러스터를 할당할 수 있습니다.
SELECT
metrics['sensor_id'] AS sensor_id,
COUNT(1) AS reading_count
FROM `TABLE_ID`
WHERE IF_NULL(metrics['origin_cluster'], 'DEFAULT_CLUSTER_ID') = CLUSTER_ATTRIBUTE('cluster_id')
GROUP BY 1
쿼리 특성
CLUSTER_ATTRIBUTE를 사용하는 쿼리에는 다음과 같은 특징이 있습니다.
sensor_id가GROUP BY절에 있으므로 구체화된 연속 뷰의 row key의 일부가 됩니다.- 이 비확정적 함수를 사용하려면 뷰를 만들 때
ignore_warnings플래그를true로 설정해야 합니다. 자세한 내용은 구체화된 뷰 만들기를 참고하세요.
SELECT *로 뷰를 쿼리하면 결과가 다음과 비슷하게 표시됩니다.
| sensor_id | reading_count |
|---|---|
| sensor-1234 | 25 |
| sensor-5678 | 68 |
제한사항
비확정적 CLUSTER_ATTRIBUTE 함수를 사용하면 엄격한 라우팅 요구사항이 도입됩니다.
- 멀티 클러스터 라우팅은 지원되지 않습니다. 함수 출력은 쿼리를 실행하는 실제 클러스터에 따라 다르므로 멀티 클러스터 라우팅은 비확정적 결과를 생성합니다.
- 단일 클러스터 라우팅 사용:
CLUSTER_ATTRIBUTE를 사용하는 연속 구체화된 뷰를 쿼리할 때는 단일 클러스터 라우팅용으로 구성된 앱 프로필을 사용합니다. - 지정된 클러스터로 라우팅: 뷰를 특정
클러스터로 격리하는 경우(예:
WHERE CLUSTER_ATTRIBUTE('cluster_id') = 'my-reporting-cluster') 앱 프로필을 해당 클러스터로 직접 연결합니다. 다른 클러스터에서 뷰가 채워지지 않으므로 다른 클러스터를 쿼리하면 빈 결과가 반환됩니다.
인코딩
SQL로 구체화된 연속 뷰를 쿼리하는 경우 SQL이 결과를 유형이 지정된 열로 노출하므로 집계된 값이 인코딩되는 방식을 알 필요가 없습니다.
ReadRows를 사용하여 뷰에서 읽는 경우 읽기 요청에서 집계된 데이터를 디코딩해야 합니다. ReadRows 요청에 대한 자세한 내용은
읽기를 참고하세요.
구체화된 연속 뷰의 집계된 값은 뷰 정의의 열 출력 유형에 따라 다음 표에 설명된 인코딩을 사용하여 저장됩니다.
| 유형 | 인코딩 |
|---|---|
| BOOL | 1바이트 값, 1 = true, 0 = false |
| BYTES | 인코딩 없음 |
| INT64 (또는 INT, SMALLINT, INTEGER, BIGINT, TINYINT, BYTEINT) | 64비트 빅 엔디언 |
| FLOAT64 | NaN 및 +/-inf를 제외한 64비트 IEEE 754 |
| STRING | UTF-8 |
| TIME/TIMESTAMP | 유닉스 시간 이후의 마이크로초 수를 나타내는 64비트 정수 (GoogleSQL과 일관됨) |