자습서: Snowflake의 JSON 기본 사항¶
소개¶
이 자습서에서는 Snowflake와 함께 JSON을 사용하는 기본 사항에 대해 알아봅니다.
알아볼 내용¶
이 자습서에서는 다음 작업을 수행하는 방법을 알아봅니다.
공용 S3 버킷의 샘플 JSON 데이터를 Snowflake 테이블에서
variant
유형의 열에 업로드합니다.테이블의 JSON 데이터에 대한 간단한 쿼리를 테스트합니다.
JSON 데이터를 관계형 표현으로 평면화하고 다른 테이블에 저장하는 FLATTEN 함수를 탐색합니다.
평면화된 버전의 데이터에 행을 삽입할 때 고유성을 보장할 방법을 살펴보십시오.
전제 조건¶
이 자습서에서는 다음과 같이 가정합니다.
Amazon AWS를 사용하도록 구성된 Snowflake 계정과 데이터베이스, 테이블 및 가상 웨어하우스 오브젝트를 만드는 데 필요한 권한을 부여하는 역할을 가진 사용자가 있습니다.
SnowSQL(CLI 클라이언트) 이 설치되어 있습니다.
20분만에 Snowflake 시작하기 자습서에서는 이러한 요구 사항을 충족하기 위한 관련 단계별 지침을 제공합니다.
Snowflake는 이 자습서에서 사용할 공용 S3 버킷의 샘플 데이터 파일을 제공합니다. 하지만 시작하기 전에 이 자습서에 따라 실습하기 위한 데이터베이스, 테이블, 가상 웨어하우스, 외부 스테이지를 만들어야 합니다. 이들은 대부분의 Snowflake 활동에 필요한 기본 Snowflake 오브젝트입니다.
샘플 데이터 파일 정보¶
이 자습서에서는 공개 S3 버킷에 제공된 다음 샘플 애플리케이션 이벤트 JSON 데이터를 사용합니다.
{
"device_type": "server",
"events": [
{
"f": 83,
"rv": "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19",
"t": 1437560931139,
"v": {
"ACHZ": 42869,
"ACV": 709489,
"DCA": 232,
"DCV": 62287,
"ENJR": 2599,
"ERRS": 205,
"MXEC": 487,
"TMPI": 9
},
"vd": 54,
"z": 1437644222811
},
{
"f": 1000083,
"rv": "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22",
"t": 1437036965027,
"v": {
"ACHZ": 6953,
"ACV": 346795,
"DCA": 250,
"DCV": 46066,
"ENJR": 9033,
"ERRS": 615,
"MXEC": 0,
"TMPI": 112
},
"vd": 626,
"z": 1437660796958
}
],
"version": 2.6
}
이 데이터는 애플리케이션이 S3에 업로드하는 샘플 이벤트를 나타냅니다. 서버, 휴대폰, 브라우저와 같은 다양한 디바이스 및 애플리케이션이 이벤트를 게시합니다. 일반적인 데이터 수집 상황에서 확장 가능한 웹 엔드포인트는 다양한 소스에서 POSTed 데이터를 수집하여 큐 시스템에 씁니다. 그러면 수집 서비스/유틸리티가 S3 버킷에 데이터를 쓰며, 여기에서 사용자는 데이터를 Snowflake로 로드할 수 있습니다.
샘플 데이터는 다음 개념을 보여줍니다.
애플리케이션은 이벤트를 일괄적으로 그룹화하도록 선택할 수 있습니다. 배치는 해당 배치의 모든 이벤트에 공통적인 헤더 정보를 포함하는 컨테이너입니다. 예를 들어 이전의 JSON은 공통적인 헤더 정보(이벤트를 생성한
device_type
및version
)가 있는 두 이벤트의 배치입니다.Amazon S3는 폴더 개념을 사용한 버킷 구성을 지원합니다. 애플리케이션은 이 기능을 활용하여 이벤트 데이터를 분할할 수 있습니다. 분할 구성표는 일반적으로 이벤트가 S3에 작성된 이벤트 날짜와 함께 이벤트를 생성한 애플리케이션 또는 위치와 같은 세부 정보를 식별합니다. 이러한 분할 구성표를 사용하면 단일 COPY 명령을 사용해 분할된 데이터의 일부를 Snowflake에 복사할 수 있습니다. 예를 들어 처음에 테이블을 채울 때 시간, 데이터, 월 또는 연도별로 이벤트 데이터를 복사할 수 있습니다.
예:
s3://bucket_name/application_a/2016/07/01/11/
s3://bucket_name/application_b/location_c/2016/07/01/14/
application_a
,application_b
,location_c
등은 경로에 있는 모든 데이터의 원본에 대한 세부 정보를 식별합니다. 데이터는 작성된 날짜별로 구성할 수 있습니다. 선택 사항인 24시간 디렉터리는 각 디렉터리의 데이터 양을 줄입니다.참고
S3는 Snowflake에서 사용하는 각 COPY 문과 함께 디렉터리 목록을 전송하므로 각 디렉터리의 파일 수를 줄이면 COPY 문의 성능이 향상됩니다. 시간마다 10~15분 단위로 폴더를 생성하는 것을 고려할 수도 있습니다.
S3 버킷에 제공된 샘플 데이터는 유사한 분할 구성표를 사용합니다. COPY 명령에서 이벤트 데이터를 복사할 특정 폴더 경로를 지정합니다.
데이터베이스, 테이블, 웨어하우스, 외부 스테이지 만들기¶
다음 문을 실행하여 이 자습서에 따라 실습하는 데 필요한 데이터베이스, 테이블, 가상 웨어하우스, 외부 스테이지를 만듭니다. 자습서를 마친 후 이러한 오브젝트를 삭제할 수 있습니다.
CREATE OR REPLACE DATABASE mydatabase; USE SCHEMA mydatabase.public; CREATE OR REPLACE TABLE raw_source ( SRC VARIANT); CREATE OR REPLACE WAREHOUSE mywarehouse WITH WAREHOUSE_SIZE='X-SMALL' AUTO_SUSPEND = 120 AUTO_RESUME = TRUE INITIALLY_SUSPENDED=TRUE; USE WAREHOUSE mywarehouse; CREATE OR REPLACE STAGE my_stage URL = 's3://snowflake-docs/tutorials/json';
다음 사항을 참고하십시오.
CREATE DATABASE
문으로 데이터베이스를 만듭니다. 데이터베이스에는 ‘public’이라는 스키마가 자동으로 포함됩니다.USE SCHEMA
문으로 현재 사용자 세션에 대한 활성 데이터베이스와 스키마를 지정합니다. 이제 데이터베이스를 지정하면 요청 시마다 이름을 입력할 필요 없이 이 데이터베이스에서 작업을 수행할 수 있습니다.CREATE TABLE
문으로 JSON 데이터의 대상 테이블을 만듭니다.CREATE WAREHOUSE
문으로 처음에 일시 중단되는 웨어하우스를 만듭니다. 또한 이 문으로 AUTO_RESUME = true가 설정되어, 컴퓨팅 리소스가 필요한 SQL 문을 실행할 때 웨어하우스를 자동으로 시작하게 됩니다.USE WAREHOUSE
문으로 현재 사용자 세션에 대한 활성 웨어하우스로 만든 웨어하우스를 지정합니다.CREATE STAGE
문으로 이 자습서의 샘플 파일이 포함된 S3 버킷을 가리키는 외부 스테이지를 생성합니다.
데이터를 대상 테이블로 복사¶
COPY INTO <테이블> 을 실행하여 스테이징된 데이터를 대상 RAW_SOURCE
테이블에 로드합니다.
COPY INTO raw_source
FROM @my_stage/server/2.6/2016/07/15/15
FILE_FORMAT = (TYPE = JSON);
이 명령으로 외부 스테이지의 지정된 경로에서 대상 RAW_SOURCE
테이블로 새 데이터를 전부 복사합니다. 이 예에서 지정된 경로의 대상은 2016년 7월 15일 15시(3 PM)에 생성된 데이터입니다. Snowflake는 각 파일의 S3 ETag 값이 한 번만 복사되는지 확인합니다.
SELECT 쿼리를 실행하여 데이터가 성공적으로 복사되었는지 확인합니다.
SELECT * FROM raw_source;
쿼리에서 반환되는 결과는 다음과 같습니다.
+-----------------------------------------------------------------------------------+
| SRC |
|-----------------------------------------------------------------------------------|
| { |
| "device_type": "server", |
| "events": [ |
| { |
| "f": 83, |
| "rv": "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19", |
| "t": 1437560931139, |
| "v": { |
| "ACHZ": 42869, |
| "ACV": 709489, |
| "DCA": 232, |
| "DCV": 62287, |
| "ENJR": 2599, |
| "ERRS": 205, |
| "MXEC": 487, |
| "TMPI": 9 |
| }, |
| "vd": 54, |
| "z": 1437644222811 |
| }, |
| { |
| "f": 1000083, |
| "rv": "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22", |
| "t": 1437036965027, |
| "v": { |
| "ACHZ": 6953, |
| "ACV": 346795, |
| "DCA": 250, |
| "DCV": 46066, |
| "ENJR": 9033, |
| "ERRS": 615, |
| "MXEC": 0, |
| "TMPI": 112 |
| }, |
| "vd": 626, |
| "z": 1437660796958 |
| } |
| ], |
| "version": 2.6 |
| } |
+-----------------------------------------------------------------------------------+
이 샘플 JSON 데이터에는 두 가지 이벤트가 있습니다. device_type
및 version
키 값은 특정 디바이스의 이벤트에 대한 데이터 소스 및 버전을 식별합니다.
데이터 쿼리¶
이 섹션에서는 JSON 데이터를 쿼리하는 SELECT 문을 탐색합니다.
device_type
을 검색합니다.SELECT src:device_type FROM raw_source;
쿼리에서 반환되는 결과는 다음과 같습니다.
+-----------------+ | SRC:DEVICE_TYPE | |-----------------| | "server" | +-----------------+
이 쿼리는
src:device_type
표기법을 사용하여 검색할 열 이름과 JSON 요소 이름을 지정합니다. 이 표기법은 익숙한 SQLtable.column
표기법과 유사합니다. Snowflake를 사용하면 Snowflake가 JSON 데이터에 삽입된 스키마 정의에서 동적으로 파생되는 상위 열 내에 하위 열을 지정할 수 있습니다. 자세한 내용은 반정형 데이터 쿼리하기 섹션을 참조하십시오.참고
열 이름은 대/소문자를 구분하지 않지만, JSON 요소 이름은 대/소문자를 구분합니다.
따옴표 없는
device_type
값을 검색합니다.이전의 쿼리는 JSON 데이터 값을 따옴표로 묶어 반환합니다. 데이터를 특정 데이터 타입(이 예제에서는 문자열)으로 캐스팅하여 따옴표를 제거할 수 있습니다.
또한 이 쿼리는 별칭을 사용하여 열에 이름을 선택적으로 할당합니다.
SELECT src:device_type::string AS device_type FROM raw_source;
쿼리에서 반환되는 결과는 다음과 같습니다.
+-------------+ | DEVICE_TYPE | |-------------| | server | +-------------+
배열 이벤트 오브젝트 내에 중첩된 반복
f
키를 검색합니다.샘플 JSON 데이터는
events
배열을 포함합니다. 배열의 각 이벤트 오브젝트에는 표시된 것과 같은f
필드가 있습니다.{ "device_type": "server", "events": [ { "f": 83, .. } { "f": 1000083, .. } ]}
이러한 중첩 키를 검색하려면 FLATTEN 함수를 사용할 수 있습니다. 이 함수는 이벤트를 별도의 행으로 평면화합니다.
SELECT value:f::number FROM raw_source , LATERAL FLATTEN( INPUT => SRC:events );
쿼리에서 반환되는 결과는 다음과 같습니다.
+-----------------+ | VALUE:F::NUMBER | |-----------------| | 83 | | 1000083 | +-----------------+
value
는 FLATTEN 함수가 반환하는 열 중 하나입니다. 다음 단계에서는 FLATTEN 함수 사용에 대해 더 많은 세부 정보를 제공합니다.
데이터 스큐 데이터¶
FLATTEN 은 VARIANT, OBJECT 또는 ARRAY 열의 래터럴 뷰를 생성하는 테이블 함수입니다. 이 단계에서는 이 함수를 사용하여 다양한 수준의 평면화를 탐색합니다.
베리언트 열의 배열 오브젝트 평면화하기¶
FLATTEN
함수를 사용하여 events
배열의 이벤트 오브젝트를 별도의 행으로 평면화할 수 있습니다. 함수 출력에는 이러한 개별 이벤트를 저장하는 VALUE 열이 포함됩니다.
그런 다음 LATERAL 한정자를 사용하여 FLATTEN
함수 출력을 오브젝트 외부의 정보(이 예에서는 device_type
및 version
)와 조인할 수 있습니다.
각 이벤트에 대한 데이터 쿼리:
SELECT src:device_type::string, src:version::String, VALUE FROM raw_source, LATERAL FLATTEN( INPUT => SRC:events );
쿼리에서 반환되는 결과는 다음과 같습니다.
+-------------------------+---------------------+-------------------------------------------------------------------------------+ | SRC:DEVICE_TYPE::STRING | SRC:VERSION::STRING | VALUE | |-------------------------+---------------------+-------------------------------------------------------------------------------| | server | 2.6 | { | | | | "f": 83, | | | | "rv": "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19", | | | | "t": 1437560931139, | | | | "v": { | | | | "ACHZ": 42869, | | | | "ACV": 709489, | | | | "DCA": 232, | | | | "DCV": 62287, | | | | "ENJR": 2599, | | | | "ERRS": 205, | | | | "MXEC": 487, | | | | "TMPI": 9 | | | | }, | | | | "vd": 54, | | | | "z": 1437644222811 | | | | } | | server | 2.6 | { | | | | "f": 1000083, | | | | "rv": "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22", | | | | "t": 1437036965027, | | | | "v": { | | | | "ACHZ": 6953, | | | | "ACV": 346795, | | | | "DCA": 250, | | | | "DCV": 46066, | | | | "ENJR": 9033, | | | | "ERRS": 615, | | | | "MXEC": 0, | | | | "TMPI": 112 | | | | }, | | | | "vd": 626, | | | | "z": 1437660796958 | | | | } | +-------------------------+---------------------+-------------------------------------------------------------------------------+
CREATE TABLE AS SELECT 문을 사용하여 이전 쿼리 결과를 테이블에 저장합니다.
CREATE OR REPLACE TABLE flattened_source AS SELECT src:device_type::string AS device_type, src:version::string AS version, VALUE AS src FROM raw_source, LATERAL FLATTEN( INPUT => SRC:events );
결과 테이블을 쿼리합니다.
SELECT * FROM flattened_source;
쿼리에서 반환되는 결과는 다음과 같습니다.
+-------------+---------+-------------------------------------------------------------------------------+ | DEVICE_TYPE | VERSION | SRC | |-------------+---------+-------------------------------------------------------------------------------| | server | 2.6 | { | | | | "f": 83, | | | | "rv": "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19", | | | | "t": 1437560931139, | | | | "v": { | | | | "ACHZ": 42869, | | | | "ACV": 709489, | | | | "DCA": 232, | | | | "DCV": 62287, | | | | "ENJR": 2599, | | | | "ERRS": 205, | | | | "MXEC": 487, | | | | "TMPI": 9 | | | | }, | | | | "vd": 54, | | | | "z": 1437644222811 | | | | } | | server | 2.6 | { | | | | "f": 1000083, | | | | "rv": "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22", | | | | "t": 1437036965027, | | | | "v": { | | | | "ACHZ": 6953, | | | | "ACV": 346795, | | | | "DCA": 250, | | | | "DCV": 46066, | | | | "ENJR": 9033, | | | | "ERRS": 615, | | | | "MXEC": 0, | | | | "TMPI": 112 | | | | }, | | | | "vd": 626, | | | | "z": 1437660796958 | | | | } | +-------------+---------+-------------------------------------------------------------------------------+
별도의 열에 오브젝트 키 평면화하기¶
이전 예제에서는 events
배열의 이벤트 오브젝트를 별도의 행으로 평면화했습니다. 결과 flattened_source
테이블은 VARIANT 유형의 src
열에 이벤트 구조를 유지했습니다.
VARIANT 유형의 src
열에 이벤트 오브젝트를 유지하는 한 가지 이점은 이벤트 형식이 변경될 때 그러한 테이블을 다시 만들고 다시 채울 필요가 없다는 점입니다. 하지만 다음 쿼리에서 보듯이 이벤트 오브젝트의 개별 키를 별도 유형의 열로 복사하는 옵션도 있습니다.
다음 CREATE TABLE AS SELECT 문으로 별도의 열에 저장된 이벤트 오브젝트 키를 사용하여 events
라는 새 테이블을 만듭니다. 각 값은 이중 콜론(::) 뒤에 타입이 오는 형식으로 값에 적합한 데이터 타입으로 캐스팅됩니다. 캐스팅을 생략하면, 열이 VARIANT 데이터 타입인 것으로 가정되며 모든 값을 가질 수 있습니다.
create or replace table events as
select
src:device_type::string as device_type
, src:version::string as version
, value:f::number as f
, value:rv::variant as rv
, value:t::number as t
, value:v.ACHZ::number as achz
, value:v.ACV::number as acv
, value:v.DCA::number as dca
, value:v.DCV::number as dcv
, value:v.ENJR::number as enjr
, value:v.ERRS::number as errs
, value:v.MXEC::number as mxec
, value:v.TMPI::number as tmpi
, value:vd::number as vd
, value:z::number as z
from
raw_source
, lateral flatten ( input => SRC:events );
이 문에서는 EVENTS.SRC:V 키의 중첩 데이터를 스큐하여 각 값에 대한 별도의 열을 추가합니다. 이 문에서는 각 키/값 페어에 대한 행이 출력됩니다. 다음 출력은 새 events
테이블의 첫 레코드 2개를 보여줍니다.
SELECT * FROM events;
+-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
| DEVICE_TYPE | VERSION | F | RV | T | ACHZ | ACV | DCA | DCV | ENJR | ERRS | MXEC | TMPI | VD | Z |
|-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------|
| server | 2.6 | 83 | "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19" | 1437560931139 | 42869 | 709489 | 232 | 62287 | 2599 | 205 | 487 | 9 | 54 | 1437644222811 |
| server | 2.6 | 1000083 | "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22" | 1437036965027 | 6953 | 346795 | 250 | 46066 | 9033 | 615 | 0 | 112 | 626 | 1437660796958 |
+-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
데이터 업데이트¶
이 자습서에서 지금까지 다음을 수행했습니다.
S3 버킷의 샘플 JSON 이벤트 데이터를
RAW_SOURCE
테이블로 복사하고 간단한 쿼리를 살펴봤습니다.또한 JSON 데이터를 평면화하고 데이터의 관계형 표시를 얻기 위한 FLATTEN 함수도 살펴봤습니다. 예를 들어 이벤트 키를 추출하고 다른 EVENTS 테이블의 별도 열에 키를 저장했습니다.
처음에는 자습서에서 여러 원본이 이벤트를 생성하고 웹 엔드포인트가 이를 S3 버킷에 저장하는 애플리케이션 시나리오를 설명합니다. S3 버킷에 새 이벤트가 추가되면 스크립트를 사용하여 새 데이터를 RAW_SOURCE
테이블 에 연속적으로 복사할 수 있습니다. 하지만 새 이벤트 데이터만 EVENTS
테이블에 삽입하려면 어떻게 해야 할까요?
데이터 일관성을 유지하는 방법은 무척 많습니다. 이 섹션에서는 두 가지 옵션을 설명합니다.
기본 키 열을 사용해 비교하기¶
이 섹션에서는 EVENTS
테이블에 기본 키를 추가합니다. 그런 다음 기본 키로 고유성을 보장합니다.
JSON 데이터가 고유하고 기본 키에 대한 좋은 후보가 될 수 있는 값인지 확인합니다. 예를 들어
src:device_type
과value:rv
의 조합이 기본 키가 될 수 있다고 가정합니다. 이러한 두 JSON 키는EVENTS
테이블의DEVICE_TYPE
및RV
열에 해당합니다.참고
Snowflake는 기본 키 제약 조건을 적용하지 않습니다. 대신, 제약 조건은 Information Schema에서 자연 키를 식별하는 메타데이터의 역할을 합니다.
EVENTS
테이블에 기본 키 제약 조건을 추가합니다.ALTER TABLE events ADD CONSTRAINT pk_DeviceType PRIMARY KEY (device_type, rv);
RAW_SOURCE
테이블에 새 JSON 이벤트 레코드를 삽입합니다.insert into raw_source select PARSE_JSON ('{ "device_type": "cell_phone", "events": [ { "f": 79, "rv": "786954.67,492.68,3577.48,40.11,343.00,345.8,0.22,8765.22", "t": 5769784730576, "v": { "ACHZ": 75846, "ACV": 098355, "DCA": 789, "DCV": 62287, "ENJR": 2234, "ERRS": 578, "MXEC": 999, "TMPI": 9 }, "vd": 54, "z": 1437644222811 } ], "version": 3.2 }');
기본 키 값에 대한 비교에 따라
RAW_SOURCE
테이블에 추가한 새 레코드를EVENTS
테이블에 삽입합니다.insert into events select src:device_type::string , src:version::string , value:f::number , value:rv::variant , value:t::number , value:v.ACHZ::number , value:v.ACV::number , value:v.DCA::number , value:v.DCV::number , value:v.ENJR::number , value:v.ERRS::number , value:v.MXEC::number , value:v.TMPI::number , value:vd::number , value:z::number from raw_source , lateral flatten( input => src:events ) where not exists (select 'x' from events where events.device_type = src:device_type and events.rv = value:rv);
EVENTS
테이블을 쿼리하면 추가된 행이 표시됩니다.select * from EVENTS;
쿼리에서 반환되는 결과는 다음과 같습니다.
+-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+ | DEVICE_TYPE | VERSION | F | RV | T | ACHZ | ACV | DCA | DCV | ENJR | ERRS | MXEC | TMPI | VD | Z | |-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------| | server | 2.6 | 83 | "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19" | 1437560931139 | 42869 | 709489 | 232 | 62287 | 2599 | 205 | 487 | 9 | 54 | 1437644222811 | | server | 2.6 | 1000083 | "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22" | 1437036965027 | 6953 | 346795 | 250 | 46066 | 9033 | 615 | 0 | 112 | 626 | 1437660796958 | | cell_phone | 3.2 | 79 | "786954.67,492.68,3577.48,40.11,343.00,345.8,0.22,8765.22" | 5769784730576 | 75846 | 98355 | 789 | 62287 | 2234 | 578 | 999 | 9 | 54 | 1437644222811 | +-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
모든 열을 사용해 비교하기¶
JSON 데이터에 기본 키 후보가 될 수 있는 필드가 없으면 RAW_SOURCE
테이블의 모든 반복 JSON 키를 EVENTS
테이블의 해당 열 값과 비교할 수 있습니다.
기존 EVENTS
테이블을 변경할 필요는 없습니다.
RAW_SOURCE
테이블에 새 JSON 이벤트 레코드를 삽입합니다.insert into raw_source select parse_json ('{ "device_type": "web_browser", "events": [ { "f": 79, "rv": "122375.99,744.89,386.99,12.45,78.08,43.7,9.22,8765.43", "t": 5769784730576, "v": { "ACHZ": 768436, "ACV": 9475, "DCA": 94835, "DCV": 88845, "ENJR": 8754, "ERRS": 567, "MXEC": 823, "TMPI": 0 }, "vd": 55, "z": 8745598047355 } ], "version": 8.7 }');
모든 반복 키 값에 대한 비교에 따라
RAW_SOURCE
테이블의 새 레코드를EVENTS
테이블에 삽입합니다.insert into events select src:device_type::string , src:version::string , value:f::number , value:rv::variant , value:t::number , value:v.ACHZ::number , value:v.ACV::number , value:v.DCA::number , value:v.DCV::number , value:v.ENJR::number , value:v.ERRS::number , value:v.MXEC::number , value:v.TMPI::number , value:vd::number , value:z::number from raw_source , lateral flatten( input => src:events ) where not exists (select 'x' from events where events.device_type = src:device_type and events.version = src:version and events.f = value:f and events.rv = value:rv and events.t = value:t and events.achz = value:v.ACHZ and events.acv = value:v.ACV and events.dca = value:v.DCA and events.dcv = value:v.DCV and events.enjr = value:v.ENJR and events.errs = value:v.ERRS and events.mxec = value:v.MXEC and events.tmpi = value:v.TMPI and events.vd = value:vd and events.z = value:z);
EVENTS
테이블을 쿼리하면 추가된 행이 표시됩니다.select * from EVENTS;
쿼리에서 반환되는 결과는 다음과 같습니다.
+-------------+---------+---------+----------------------------------------------------------------------+---------------+--------+--------+-------+-------+------+------+------+------+-----+---------------+ | DEVICE_TYPE | VERSION | F | RV | T | ACHZ | ACV | DCA | DCV | ENJR | ERRS | MXEC | TMPI | VD | Z | |-------------+---------+---------+----------------------------------------------------------------------+---------------+--------+--------+-------+-------+------+------+------+------+-----+---------------| | server | 2.6 | 83 | "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19" | 1437560931139 | 42869 | 709489 | 232 | 62287 | 2599 | 205 | 487 | 9 | 54 | 1437644222811 | | server | 2.6 | 1000083 | "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22" | 1437036965027 | 6953 | 346795 | 250 | 46066 | 9033 | 615 | 0 | 112 | 626 | 1437660796958 | | cell_phone | 3.2 | 79 | "786954.67,492.68,3577.48,40.11,343.00,345.8,0.22,8765.22" | 5769784730576 | 75846 | 98355 | 789 | 62287 | 2234 | 578 | 999 | 9 | 54 | 1437644222811 | | web_browser | 8.7 | 79 | "122375.99,744.89,386.99,12.45,78.08,43.7,9.22,8765.43" | 5769784730576 | 768436 | 9475 | 94835 | 88845 | 8754 | 567 | 823 | 0 | 55 | 8745598047355 | +-------------+---------+---------+----------------------------------------------------------------------+---------------+--------+--------+-------+-------+------+------+------+------+-----+---------------+
축하합니다!¶
축하합니다. 이 자습서를 성공적으로 완료하셨습니다.
자습서 주요 사항¶
논리적이고 세분화된 경로를 사용하여 S3 버킷의 이벤트 데이터를 분할하면 단일 명령을 통해 분할된 데이터의 하위 세트를 Snowflake로 복사할 수 있습니다.
익숙한 SQL
table.column
표기법과 유사한 Snowflake의column:key
표기법을 사용하면 열 안의 열(즉, 하위 열)을 효과적으로 쿼리할 수 있으며, 이는 JSON 데이터에 포함된 스키마 정의를 기반으로 동적으로 파생됩니다.FLATTEN 함수를 사용하면 JSON 데이터를 별도의 열로 구문 분석할 수 있습니다.
스테이징된 데이터 파일과 비교하여 테이블 데이터를 업데이트하기 위한 여러 옵션을 사용할 수 있습니다.
자습서 정리(선택 사항)¶
자습서를 시작하기 전의 상태로 시스템을 되돌리려면 다음 DROP <오브젝트> 명령을 실행합니다.
DROP DATABASE IF EXISTS mydatabase; DROP WAREHOUSE IF EXISTS mywarehouse;
데이터베이스를 삭제하면 테이블과 같은 모든 하위 데이터베이스 오브젝트가 자동으로 제거됩니다.