차등 개인정보 보호로 보호되는 데이터 쿼리하기

이 항목은 분석가가 차등 개인정보 보호로 보호되는 데이터(즉, 개인정보 보호 테이블과 뷰)에 대해 쿼리를 실행하고, 쿼리에서 반환된 결과를 이해하고 조정하는 데 도움이 됩니다.

개인정보 보호 테이블에 대해 쿼리를 실행하려면 사용자에게 테이블에 대한 SELECT 권한이 있어야 합니다.

제한 사항

  • 차등 개인정보 보호는 Snowflake 데이터 타입, 연산자, 쿼리 구문 및 함수의 하위 집합을 지원합니다. 쿼리에 사용할 수 있는 지원되는 SQL 목록은 차등 개인정보 보호 SQL 참조 섹션을 참조하십시오.

  • 개인정보가 보호되는 테이블에 대한 쿼리는 Snowflake에서 얼마나 많은 노이즈를 추가할지 결정하기 위해 추가 계산을 실행해야 하므로 시간이 더 오래 걸립니다. 기본 쿼리의 경우 지연 시간은 최소 7초입니다. 다음과 같은 복잡한 쿼리는 훨씬 더 오랜 시간이 걸릴 수 있습니다.

    • 많은 조인과 하위 쿼리가 있는 쿼리.

    • 결과에 여러 행을 출력하는 쿼리(예: 수백 또는 수천 개의 그룹을 생성하는 GROUP BY 절을 사용하는 경우).

쿼리 기본 사항

이 섹션에서는 개인정보 보호 테이블에 대해 실행할 때 성공하는 쿼리의 기본 구성 요소에 대해 설명합니다. 다음 내용이 포함됩니다.

데이터 집계하기

개인정보 보호 테이블에 대한 모든 쿼리는 개별 레코드를 검색하는 대신 결과를 집계해야 합니다. 최종 결과가 집계되는 한 쿼리의 모든 부분이 집계 함수를 사용할 필요는 없습니다.

COUNT 함수를 제외하고, 쿼리는 열에 개인정보 보호 도메인 이 없는 경우 열을 집계할 수 없습니다.

지원되는 집계 목록은 집계 함수 섹션을 참조하십시오.

조인 사용하기

다음 섹션에서는 차등 개인정보 보호 쿼리에서 조인을 사용하기 위한 지침을 제공합니다.

개인정보 보호 테이블 두 개를 조인하는 것이 개인정보 보호 도메인에 미치는 영향에 대해 알아보려면 개인정보 보호 도메인 및 조인 섹션을 참조하십시오.

조인 연산자

각 조인은 단일 연산자를 사용하는 동등 조인이어야 합니다. 예를 들어, t1.c1 == t2.c1 은 지원되지만, col1 > col2col1 + 10 = col2 는 지원되지 않습니다. 조건 없는 조인은 지원되지 않습니다.

조인에는 JOIN 연산자를 사용해야 합니다. 조인에 대한 WHERE 구문은 지원되지 않습니다. 조인 구문에 대한 자세한 내용은 조인 구현하기 섹션을 참조하십시오.

지원되는 조인

차등 개인정보 보호 쿼리의 조인은 다음 중 하나여야 합니다.

  • INNER

  • { LEFT | RIGHT | FULL } OUTER

  • NATURAL

조인의 양쪽 모두 쿼리 패턴이 동일해야 합니다. 예를 들어, 다음 조인은 지원됩니다.

양쪽이 모두 식별자

SELECT COUNT(*)
FROM t1 INNER JOIN t2 ON t1.a=t2.a;
Copy

양쪽이 모두 하위 쿼리

SELECT COUNT(*)
FROM (SELECT a, SUM(b) FROM t1 GROUP BY a) AS g1
    INNER JOIN (SELECT * FROM t2) AS g2
    ON g1.a=g2.a;
Copy

식별자와 하위 쿼리를 조인하는 기능은 현재 지원되지 않습니다.

조인과 관련된 지원되는 쿼리 구문에 대한 내용은 쿼리 구문 섹션을 참조하십시오.

조인에서 엔터티 키 사용하기

엔터티 수준 개인정보 보호 로 보호되는 테이블 작업을 수행하는 경우, 특히 의미 체계적으로 쿼리를 변경하지 않는 경우 엔터티 키 열을 조인 키의 일부로 포함하면 노이즈의 양을 최소화할 수 있습니다.

예를 들어, 엔터티가 고객인 다음 테이블이 있다고 가정해 보겠습니다.

테이블

설명

customers

각 행이 고객이고 customer_id 가 있는 고객 디렉터리.

transactions

각 고객이 여러 트랜잭션을 가질 수 있는 고객 트랜잭션.

transaction_lines

트랜잭션에서 구매한 고유 항목. 하나의 트랜잭션에는 여러 행이 있을 수 있습니다.

모범 사례를 따르는 경우, 데이터 공급자는 각 테이블이 엔터티 키 customer_id 를 갖도록 데이터를 정형화했습니다. 이 데이터 스키마의 경우, 각 트랜잭션 라인은 하나의 트랜잭션에만 속할 수 있으며, 각 트랜잭션은 한 명의 고객에게만 속할 수 있습니다. 이러한 관계는 데이터 자체에서는 명확하게 드러나지 않으므로 추가 정보가 없으면 차등 개인정보 보호를 위해 추가되는 노이즈 양이 필요 이상으로 많아질 것입니다.

엔터티 키 customer_id 를 조인 키의 일부로 포함하면 중복되더라도 노이즈의 양을 최소화할 수 있습니다. 예를 들어, transactions 테이블을 transaction_lines 와 조인하는 경우 일반적으로 transaction_id 조인 키만 필요합니다. 그러나 transaction_idcustomer_id 모두에서 조인하면 노이즈가 줄어듭니다.

데이터 타입 및 개인정보 보호 도메인

두 테이블을 조인하는 경우 양쪽의 조인 키 열의 데이터 타입이 동일해야 합니다. 차등 개인 정보 보호의 경우 열의 데이터 타입에는 개인정보 보호 도메인 이 있는지 여부가 포함됩니다.

예를 들어, 개인 정보 보호 테이블 transactions 와 보호되지 않는 테이블 product_lookup 이 있고 이를 product_id 에서 조인하려는 경우, 두 테이블의 product_id 열은 동일한 데이터 타입(예: 문자열)이어야 하며 각각 개인정보 보호 도메인을 가져야 합니다.

이러한 요구 사항을 충족하려면 분석가의 관리자가 데이터 공급자가 정의하는 것과 마찬가지로 개인정보 보호 도메인을 정의해야 할 수도 있습니다. 테이블에 대한 개인정보 도메인을 설정하는 방법에 대한 자세한 내용은 개인정보 보호 도메인 설정하기 섹션을 참조하십시오.

고유성 요구 사항

조인으로 인해 데이터 행이 중복될 가능성이 있으며, 이로 인해 쿼리 결과에 추가되는 노이즈의 양이 무제한이 될 수 있습니다. 조인에서 개인정보로 보호되는 데이터가 중복되지 않도록 하려면 개인정보로 보호되는 테이블의 조인 키(즉, 테이블이 조인되는 열)가 다른 테이블의 레코드 1개와만 일치해야 합니다. 즉, 개인정보가 보호되는 테이블에 조인할 때 반대쪽의 조인 키에서 중복을 제거해야 합니다.

중요

조인에 대한 고유성 요구 사항은 엔터티 수준 개인정보 보호 로 보호되는 테이블에 대한 쿼리에 항상 적용되는 것은 아닙니다. 엔터티 수준의 개인정보 보호를 위해 쿼리는 집계하기 전 엔터티 키에서 중복을 제거해야 합니다. 이 작업이 조인 후 집계 전에 수행되는 한, 조인이 중복 제거된 데이터에 대해 수행될 필요는 없습니다. 이러한 요구 사항을 충족하는 방법에 대한 자세한 내용은 엔터티 수준 개인정보 보호로 보호되는 데이터 쿼리하기 섹션을 참조하십시오.

조인에 대한 고유성 요구 사항을 충족하기 위해 쿼리는 조인 열의 하위 집합에서 GROUP BY를 사용하여 중복 행을 하나의 결과로 그룹화할 수 있습니다.

예를 들어, patients 테이블은 차등 개인정보 보호로 보호되고 geo_lookup 테이블은 그렇지 않다고 가정해 보겠습니다. 분석가는 zip_code 에서 이 두 테이블을 조인하여 Statepatients 테이블에서 필터링을 수행할 수 있기를 원합니다. 개인정보 보호 patients 테이블의 레코드가 중복되지 않도록 하려면 쿼리는 조인 키에서 zip_code 테이블의 중복을 제거해야 합니다. geo_lookup 테이블이 이미 zip_code 에서 고유한 경우에도 이 작업을 명시적으로 수행해야 합니다. 이를 통해 Snowflake가 개인정보 보호를 올바르게 처리할 수 있습니다.

SELECT COUNT(*)
  FROM patients
  LEFT JOIN (SELECT zip_code, ANY_VALUE(state) AS residence_state
            FROM geo_lookup
            GROUP BY zip_code)
  USING zip_code
  WHERE birth_state = residence_state;
Copy

엔터티 수준 개인정보 보호로 보호되는 데이터 쿼리하기

대부분의 데이터 공급자는 차등 개인정보 보호를 구성할 때 엔터티 키를 사용하여 엔터티 수준의 개인정보 보호 를 구현합니다. 테이블이 엔터티 수준 개인정보 보호로 보호되는 경우, 엔터티당 행 수가 무제한일 수 있으면 Snowflake는 필드에 대한 집계를 허용하지 않습니다. 즉, 쿼리는 다음 요구 사항을 충족해야 합니다.

  • 쿼리의 어느 시점에 개인정보 보호 테이블은 엔터티 키에서 중복 제거되어야 합니다. 데이터 중복을 제거하는 데 사용할 수 있는 작업은 다음과 같습니다.

    • COUNT( DISTINCT <entity_key_column> )

    • GROUP BY <entity_key_column>

    • 엔터티 키만 프로젝션되는 경우 UNION(UNION ALL 제외)

  • 조인이 엔터티 키 열이 아닌 다른 조인 키를 사용하는 경우 해당 조인은 중복 제거와 집계가 있는 최종 SELECT 절 사이에서 발생할 수 없습니다.

참고

데이터 공급자가 행 수준 개인정보 보호를 구현한 경우 조인에 대한 중복 제거 요구 사항이 달라집니다. 이러한 요구 사항에 대한 자세한 내용은 고유성 요구 사항 섹션을 참조하십시오.

엔터티 수준 개인정보 보호에 대한 요구 사항을 설명하기 위해 엔터티 키 열이 patient_id 인 개인정보 보호 테이블 patients 가 있다고 가정해 보겠습니다. 또한 민감하지 않은 보호되지 않은 테이블 geo_lookup 도 있습니다. 다음 예제에서는 실패한 쿼리와 다시 작성된 버전이 성공한 쿼리를 보여줍니다.

예: 중복 제거

다음 쿼리는 중복 제거 요구 사항을 충족하지 않기 때문에 실패합니다. patients 테이블이 이미 patient_id 에서 고유한 테이블일지라도 명시적으로 중복 제거되지 않았기 때문에 쿼리가 실패합니다.

SELECT COUNT(*)
  FROM patients
  WHERE insurance_type = 'Commercial';
Copy

쿼리가 성공하도록 쿼리를 다시 작성하려면 엔터티 키 열에 고유 카운트를 포함시켜 엔터티 키에서 명시적으로 중복 제거를 수행하십시오. 예:

SELECT COUNT(DISTINCT patient_id)
  FROM patients
  WHERE insurance_type = 'Commercial';
Copy
예: 조인의 위치

다음 쿼리는 중복 제거 요구 사항을 충족하기 위해 GROUP BY 절을 사용하지만 실패합니다. 해당 테이블이 엔터티 키 열이 아닌 열을 사용하여 다른 테이블과 조인되기 때문에 실패합니다.

SELECT AVG(bmi)
  FROM (SELECT patient_id, ANY_VALUE(zip_code) AS zip_code
    FROM patients
    GROUP BY patient_id) AS p
  JOIN geo_lookup AS g
    ON p.zip_code = g.zip_code
  WHERE state='CA';
Copy

쿼리가 성공하도록 쿼리를 다시 작성하려면 조인 뒤에 GROUP BY 절을 사용합니다. 집계가 포함된 중복 제거와 SELECT 절 사이에는 조인을 수행할 수 없습니다.

SELECT AVG(bmi)
  FROM (SELECT patient_id, ANY_VALUE(bmi) as bmi, ANY_VALUE(state) as state
      FROM patients AS p
      JOIN geo_lookup AS g
        ON p.zip_code = g.zip_code
      GROUP BY patient_id)
  WHERE state='CA';
Copy

트랜잭션 수준 쿼리 실행

엔터티 수준 차등 개인정보 보호에 대한 중복 제거 요구 사항은 트랜잭션 수준 쿼리를 실행하는 데 방해가 되지 않습니다. 하지만 먼저 엔터티 수준으로 데이터를 그룹화한 다음 해당 그룹을 기준으로 집계해야 합니다.

예를 들어, doctor_visits 테이블이 있고 데이터 공급자가 엔터티 수준의 개인정보 보호를 구현하기 위해 엔터티 키 patient_id 를 정의했다고 가정해 보겠습니다. 트랜잭션 수준 쿼리의 예는 “How many doctor visits weren’t for a regular checkup?”입니다. 다음은 이 쿼리를 작성하는 방법의 예입니다.

SELECT SUM(num_visits)
  FROM (SELECT SUM((visit_reason<>'Regular checkup')::INT) AS num_visits
        WHERE visit_reason IS NOT NULL
        GROUP BY patient_id)
  WHERE num_visits > 0 AND num_visits < 20;
Copy

하위 쿼리는 patient_id 로 그룹화하여 데이터를 중복 제거합니다. 집계 열 num_visits 는 정기 검진을 위한 방문이 아닌 환자당 방문 횟수를 캡처합니다. 그런 다음 쿼리는 환자별 열에 대해 다시 집계하여 총 방문 횟수를 구합니다. 데이터에 개인정보 보호 도메인을 지정 하려면 외부 쿼리의 WHERE 절이 필요합니다.

참고

필수는 아니지만 엔터티 수준의 차등 개인정보 보호로 보호되는 테이블을 조인할 때 최상의 방법은 조인 키의 일부로 엔터티 키 열을 포함하는 것입니다(쿼리를 의미적으로 변경하지 않는 경우). 자세한 내용은 조인에서 엔터티 키 사용하기 섹션을 참조하십시오.

쿼리 결과 이해하기

개인정보가 보호된 테이블에 대한 쿼리는 집계의 정확한 값을 반환하지 않습니다. 차등 개인정보 보호는 결과에 노이즈 가 발생하여 실제 값의 근사치가 됩니다. 반환된 값은 실제 값과 충분히 달라서 개인의 데이터가 집계에 포함되었는지 여부를 숨길 수 있습니다. 이는 개인정보 보호 테이블의 총 행 수를 반환하는 쿼리(예: SELECT COUNT(*) FROM t)를 제외한 모든 쿼리에 적용됩니다.

분석가는 결과에 추가된 노이즈로 인해 쿼리의 유용성이 감소했는지 여부를 판단할 수 있어야 합니다. Snowflake는 분석가가 결과를 해석하는 데 도움이 되는 노이즈 구간 을 사용합니다. 노이즈 구간은 대부분의 경우 집계의 실제 값을 포함하는 닫힌 수학적 구간입니다. 실제 쿼리의 결과가 노이즈 구간 내에 포함될 확률은 95%입니다.

다음 함수를 쿼리에 추가하면 분석가는 노이즈 구간을 사용하여 쿼리의 유용성에 대한 결정을 내릴 수 있습니다.

  • DP_INTERVAL_LOW — 노이즈 구간의 하한을 반환합니다. 실제 값은 이 값과 같거나 더 클 가능성이 높습니다.

  • DP_INTERVAL_HIGH — 노이즈 구간의 상한을 반환합니다. 실제 값은 이 값과 같거나 더 작을 가능성이 가장 높습니다.

이러한 함수를 사용하려면 기본 쿼리에 집계 열의 별칭을 전달해야 합니다. 예를 들어, 다음 쿼리는 해당 집계에 대한 노이즈 구간과 함께 num_claims 열의 합계를 반환합니다.

SELECT SUM(num_claims) AS sum_claims,
      DP_INTERVAL_LOW(sum_claims),
      DP_INTERVAL_HIGH(sum_claims)
  FROM t1;
Copy

출력은 다음과 같을 수 있습니다.

+--------------+--------------------------------+----------------------------------+
|  sum_claims  |  dp_interval_low("sum_claims") |  dp_interval_high("sum_claims")  |
|--------------+--------------------------------+----------------------------------+
|  50          |  35                            |    75                            |
+--------------+--------------------------------+----------------------------------+

이 경우 반환 값은 50의 합입니다. 그러나 분석가는 또한 집계치의 실제 값이 35에서 75 사이라는 것을 95%의 확실성으로 확인했습니다.

결과의 노이즈를 잠재적으로 줄일 수 있는 기술에 대한 정보는 다음을 참조하십시오.

개인정보 보호 예산 지출 추적하기

ESTIMATE_REMAINING_DP_AGGREGATES 함수를 사용하여 현재 예산 윈도우 내에서(즉, 누적 개인정보 보호 손실이 0으로 재설정될 때까지) 얼마나 많은 쿼리를 더 실행할 수 있는지 추정할 수 있습니다. 추정치는 쿼리의 수가 아닌 집계의 수를 기준으로 합니다. 예를 들어, SELECT SUM(age), COUNT(age) FROM T 쿼리에는 두 개의 집계 함수 SUM(age)COUNT(age) 가 포함되어 있습니다.

ESTIMATE_REMAINING_DP_AGGREGATES 함수를 실행할 때는 동일한 사용자, 역할, 계정 등 쿼리 실행에 사용하는 정확한 조건(예: 동일한 사용자, 역할, 계정)을 사용해야 합니다.

여러 테이블을 사용하는 쿼리를 실행하는 경우 테이블당 NUMBER_OF_REMAINING_DP_AGGREGATES 를 한 번 실행한 다음 가장 낮은 ESTIMATE_REMAINING_DP_AGGREGATES 값을 예상 사용량 제한으로 사용해야 합니다.

다음 예는 일련의 쿼리가 개인정보 보호 예산 한도의 얼마나 많은 부분이 사용되었는지(즉, 쿼리의 누적 개인정보 보호 손실)와 남아 있는 집계의 추정 수에 어떤 영향을 미치는지 보여줍니다.

1. 초기 확인

my_table 테이블의 개인정보 보호 예산 수치를 살펴보겠습니다. 이 테이블에 대해 어떤 쿼리도 실행한 적이 없습니다.

SELECT * FROM TABLE(SNOWFLAKE.DATA_PRIVACY.ESTIMATE_REMAINING_DP_AGGREGATES('my_table'));
Copy

지금까지 사용된 예산 없음:

+-----------------------------------+--------------+---------------+--------------+
| NUMBER_OF_REMAINING_DP_AGGREGATES | BUDGET_LIMIT | BUDGET_WINDOW | BUDGET_SPENT |
|-----------------------------------+--------------+---------------+--------------|
|                 996               |     233      |     WEEKLY    |     0.0      |
+-----------------------------------+--------------+---------------+--------------+

2. 쿼리 실행

하나의 집계 함수로 쿼리를 실행하고 숫자를 다시 확인해 보겠습니다.

SELECT SUM(salary) FROM my_table;

-- results omitted ...

SELECT * FROM TABLE(SNOWFLAKE.DATA_PRIVACY.ESTIMATE_REMAINING_DP_AGGREGATES('my_table'));
Copy

남은 총 호출 수 추정치는 1이 감소하고 누적 개인정보 보호 손실(지출 예산)은 증가했습니다.

+-----------------------------------+--------------+---------------+--------------+
| NUMBER_OF_REMAINING_DP_AGGREGATES | BUDGET_LIMIT | BUDGET_WINDOW | BUDGET_SPENT |
|-----------------------------------+--------------+---------------+--------------|
|                 995               |     233      |     WEEKLY    |     0.6      |
+-----------------------------------+--------------+---------------+--------------+

3. 두 개의 집계 함수로 다른 쿼리 실행

SELECT SUM(age), COUNT(age) FROM my_table GROUP BY STATE;

-- results omitted ...

SELECT * FROM TABLE(SNOWFLAKE.DATA_PRIVACY.ESTIMATE_REMAINING_DP_AGGREGATES('my_table'));
Copy

남은 쿼리 수가 2 감소했습니다. 이는 추정치입니다.

+-----------------------------------+--------------+---------------+--------------+
| NUMBER_OF_REMAINING_DP_AGGREGATES | BUDGET_LIMIT | BUDGET_WINDOW | BUDGET_SPENT |
|-----------------------------------+--------------+---------------+--------------|
|                 993               |     233      |     WEEKLY    |     1.8      |
+-----------------------------------+--------------+---------------+--------------+

4. 쿼리를 다시 실행

동일한 쿼리에서도 개인정보 보호 예산이 항상 청구된다는 것을 보여주기 위해 이전 쿼리를 다시 실행해 보겠습니다. 중복된 쿼리는 실행할 때마다 동일한 개인정보 보호 손실이 발생(즉, 동일한 양의 개인정보 보호 예산을 사용)합니다.

SELECT SUM(age), COUNT(age) FROM T GROUP BY STATE;

-- results omitted ...

SELECT * FROM TABLE(SNOWFLAKE.DATA_PRIVACY.ESTIMATE_REMAINING_DP_AGGREGATES('my_table'));
Copy

쿼리 요금은 이전과 동일: 1.2 단위의 개인정보 보호 손실.

+-----------------------------------+--------------+---------------+--------------+
| NUMBER_OF_REMAINING_DP_AGGREGATES | BUDGET_LIMIT | BUDGET_WINDOW | BUDGET_SPENT |
|-----------------------------------+--------------+---------------+--------------|
|                 991               |     233      |     WEEKLY    |     3.0      |
+-----------------------------------+--------------+---------------+--------------+