4단계. 데이터 업데이트

이 자습서에서 지금까지 다음을 수행했습니다.

  • S3 버킷의 샘플 JSON 이벤트 데이터를 RAW_SOURCE 테이블로 복사하고 간단한 쿼리를 살펴봤습니다.

  • 또한 JSON 데이터를 평면화하고 데이터의 관계형 표시를 얻기 위한 FLATTEN 함수도 살펴봤습니다. 예를 들어 이벤트 키를 추출하고 다른 EVENTS 테이블의 별도 열에 키를 저장했습니다.

처음에는 자습서에서 여러 원본이 이벤트를 생성하고 웹 엔드포인트가 이를 S3 버킷에 저장하는 애플리케이션 시나리오를 설명합니다. S3 버킷에 새 이벤트가 추가되면 스크립트를 사용하여 새 데이터를 RAW_SOURCE 테이블 에 연속적으로 복사할 수 있습니다. 하지만 새 이벤트 데이터만 EVENTS 테이블에 삽입하려면 어떻게 해야 할까요?

데이터 일관성을 유지하는 방법은 무척 많습니다. 이 섹션에서는 두 가지 옵션을 설명합니다.

기본 키 열을 사용해 비교하기

이 섹션에서는 EVENTS 테이블에 기본 키를 추가합니다. 그런 다음 기본 키로 고유성을 보장합니다.

  1. JSON 데이터가 고유하고 기본 키에 대한 좋은 후보가 될 수 있는 값인지 확인합니다. 예를 들어 src:device_typevalue:rv 의 조합이 기본 키가 될 수 있다고 가정합니다. 이러한 두 JSON 키는 EVENTS 테이블의 DEVICE_TYPERV 열에 해당합니다.

    참고

    Snowflake는 기본 키 제약 조건을 적용하지 않습니다. 대신, 제약 조건은 Information Schema에서 자연 키를 식별하는 메타데이터의 역할을 합니다.

  2. EVENTS 테이블에 기본 키 제약 조건을 추가합니다.

    ALTER TABLE events ADD CONSTRAINT pk_DeviceType PRIMARY KEY (device_type, rv);
    
    Copy
  3. 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
      }');
    
    Copy
  4. 기본 키 값에 대한 비교에 따라 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);
    
    Copy

    EVENTS 테이블을 쿼리하면 추가된 행이 표시됩니다.

    select * from EVENTS;
    
    Copy

    쿼리에서 반환되는 결과는 다음과 같습니다.

    +-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
    | 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 |
    +-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
    
    Copy

모든 열을 사용해 비교하기

JSON 데이터에 기본 키 후보가 될 수 있는 필드가 없으면 RAW_SOURCE 테이블의 모든 반복 JSON 키를 EVENTS 테이블의 해당 열 값과 비교할 수 있습니다.

기존 EVENTS 테이블을 변경할 필요는 없습니다.

  1. 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
      }');
    
    Copy
  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.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);
    
    Copy

    EVENTS 테이블을 쿼리하면 추가된 행이 표시됩니다.

    select * from EVENTS;
    
    Copy

    쿼리에서 반환되는 결과는 다음과 같습니다.

    +-------------+---------+---------+----------------------------------------------------------------------+---------------+--------+--------+-------+-------+------+------+------+------+-----+---------------+
    | 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 |
    +-------------+---------+---------+----------------------------------------------------------------------+---------------+--------+--------+-------+-------+------+------+------+------+-----+---------------+
    
    Copy

다음 항목: 5단계. 정리