연속 구체화된 뷰 쿼리

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 쿼리에서 다음 집계 함수를 사용할 수 있습니다.

  • COUNT
  • SUM
  • MIN
  • MAX
  • HLL_COUNT.INIT
  • HLL_COUNT.MERGE
  • HLL_COUNT.MERGE_PARTIAL
  • ANY_VALUE
  • BIT_AND
  • BIT_OR
  • BIT_XOR
  • AVG

SELECT COUNT(*)를 사용하는 경우 다음 예와 같이 row key를 정의해야 합니다.

SELECT
  '*' AS _key,
  COUNT(*) AS count
FROM
  foo
GROUP BY
  _key;

지원되지 않는 SQL 기능

다음 SQL 기능은 사용할 수 없습니다.

  • Bigtable용 GoogleSQL에서 지원되지 않는 기능
  • ARRAY
  • ARRAY_AGG
  • ARRAY_CONCAT_AGG
  • COUNT_IF
  • CURRENT_TIME 및 대부분의 다른 비확정적 함수(예외 포함)
  • DATE, DATETIME을 출력 열로 사용 (TIMESTAMP를 사용하거나 문자열을 저장)
  • 출력의 DESC 정렬
  • DISTINCT 옵션(예: SUM(*DISTINCT* value))
  • LIMIT/OFFSET
  • SELECT *
  • 창 집계를 만드는 OVER
  • STRUCT

GROUP BY 또는 ORDER BY 절을 중첩하거나 맵 열을 만들 수도 없습니다. 추가 제한사항은 제한사항을 참고하세요.

제외된 행 방지

입력 행은 다음과 같은 경우 구체화된 연속 뷰에서 제외됩니다.

  • 행에서 1MiB가 넘는 데이터가 선택됩니다. 예를 들어 쿼리가 SELECT apple AS apples , SUM(banana) AS sum_bananas FROM my_table GROUP BY apples인 경우 applebanana 열에 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, ca 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 순서로 별도의 행에 있습니다.
  • 지정된 bazfoo가 하나 이상 있으면 출력 행의 sum_foo는 NULL이 아닌 값입니다.
  • 지정된 bazbar가 하나 이상 있으면 출력 행의 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_ID WHERE 조건은 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_idGROUP 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과 일관됨)
자세한 내용은 Data API 참조의 인코딩을 참고하세요.

다음 단계