集計ポリシーによるエンティティレベルのプライバシーの実装

エンティティレベルのプライバシーは、集計ポリシーによって提供されるプライバシー保護を強化します。エンティティレベルのプライバシーでは、各グループに最小限の行数だけでなく、最小限の固有エンティティを必ず含ませることができます。

集計ポリシーに関連するタスクと考慮事項の大部分は、エンティティレベルのプライバシーを実装しているかどうかに関係なく同じです。集計ポリシーの操作に関する一般的な情報については、 集計ポリシー をご参照ください。

エンティティレベルのプライバシーについて

エンティティ とは、論理オブジェクト(例えば、ユーザープロファイルや世帯情報)に属する属性の集合を指します。これらの属性は、データセット内のエンティティの識別に使用できます。エンティティレベルのプライバシーは、共有データセットに格納されているエンティティのプライバシーを保護するプライバシー拡張技術(PET)の機能です。クエリによって、エンティティの機密属性が複数のレコードで見つかったとしても、その属性が公開されないようにします。

エンティティレベルのプライバシーを可能にするために、Snowflakeではエンティティを識別する列を指定することができます(エンティティキー)。これにより、Snowflakeはデータセット内の特定のエンティティに属するすべての記録を識別子化することができます。たとえば、エンティティキーが列 email として定義されている場合、Snowflakeは email=joe.smith@example.com のすべての記録が同じエンティティに属していると判断できます。

1つのテーブルに複数のエンティティを定義すると、集計ポリシーは各エンティティキーに対して個別に評価されます。

ポリシーは、キー列がクエリに表示されなくてもクエリに適用されます。例えば、エンティティキー(user_id)に適用されるポリシーの場合、クエリ SELECT age FROM T1 GROUP BY age;user_id がクエリになくても各グループ内の user_id に対して min_group_size 制限を適用します。

エンティティレベルのプライバシーが ない 集計ポリシー

デフォルトでは、集計ポリシーにより、アナリストは個々の行を取得するのではなく、データを集計するクエリを実行する、つまり 行レベルのプライバシー を達成する必要があります。しかし、行レベルのプライバシーは、クエリによってエンティティの属性が複数の行(例えば、トランザクションデータを含むテーブル)で検出された場合に、その属性が公開されることを防ぐことはできません。

たとえば、あるストリーミングサービス(ActonViz)が、番組を視聴する各視聴者の電子メールアドレス(user_id)と世帯(household_id)を含むトランザクションテーブルを持っているとします。

user_id

household_id

program_id

watch_time

start_time

dave_sr@example.com

12345

1

29

2023-09-12 09:00

mary@bazco.com

23485

1

30

2023-09-12 09:00

dave_sr@example.com

12345

6

18

2023-09-11 13:00

joe@jupiterlink.com

85456

6

25

2023-09-15 22:00

junior@example.com

12345

5

30

2023-09-13 11:00

ActonVizは、集計ポリシーを使用して、少なくとも2つの記録を含むグループにデータを集約するように広告主に強制することができます。これにより、広告主が個々の記録からデータを取得することを防ぎます(行レベルのプライバシー)。それぞれの視聴者と世帯が表に一度だけ登場すれば、プライバシー保護には十分でしょう。

しかし、広告主のクエリは、視聴者とその世帯の両方の情報を知ることができます。クエリによって、世帯 12345 の記録だけで構成されるグループや、さらに悪いことに、視聴者 dave_sr の記録だけで構成されるグループが作成される可能性があります。どちらの場合も、グループ内の記録数はActonViz(1グループあたり最低2件の記録)が定める条件を満たすことになります。

エンティティレベルのプライバシーを 持つ 集計ポリシー

エンティティレベルのプライバシーを可能にするために、Snowflakeではテーブルやビューに集計ポリシーを割り当てる際に1つまたは複数のエンティティキーを指定することができます。エンティティキーが定義された後、集約制約のあるテーブルまたはビューに対するクエリによって返されるグループには、少なくとも指定した エンティティ 数が含まれている必要があります(指定した 数ではない)。

先ほどの例で、 ActonViz が各世帯を一意に識別するため、 household_id をエンティティキーとして定義したとします。各世帯のプライバシーが強化されるようになります。変更前は、 household_id = 12345 の記録だけでグループを構成することができましたが、現在は、 household_id の少なくとも2つの異なる値を含む必要があります。

エンティティキーは、テーブルの プライマリキー と同じになるとは限らないことに注意してください。この例では、 user_id をプライマリキーとして使用します。しかしこの場合、 ActonViz が複数の視聴者からなる世帯全体のプライバシーを保護したいため、 household_id をエンティティキーとして選びました。

最小グループサイズについて

すべての集計ポリシーは、最小グループサイズを指定します。エンティティレベルのプライバシーがない場合、最小グループサイズは、集計グループに含める必要がある記録数を定義します。エンティティキーが指定されている場合、最小グループサイズは、最終結果に表示されるためにグループ内に表示される必要がある 固有の エンティティの最小数を定義します。SUMやAVGのような集約関数は1つのグループを返しますが、GROUP BY列はグループ化された列の一意な値ごとに1つのグループを返す点に注意してください。

以下の列レベルのポリシーは、Snowflakeが集計グループに十分なエンティティがあるかどうかを計算する方法には影響しません:

  • 投影ポリシーは集計ポリシーの後に実施されます。

  • マスキングポリシーは、集計ポリシーの前に実施されます。集計関数やポリシーは、マスキングされたデータに対して機能します。

名前参照が複数回使用される場合(たとえば、 JOIN または UNION 演算子)、Snowflakeは各データセットの各名前参照に対して個別に最小グループサイズを強制します。これは、同じデータセットを何度も参照する場合にも当てはまります。

集計ポリシーによってエンティティレベルのプライバシーを強制する

集計ポリシーでエンティティレベルのプライバシーを強制するには、次のようにします。

  1. CREATE AGGREGATION POLICY コマンドを実行して集計ポリシーを作成する場合は、各集計グループに含める必要がある エンティティの数を指定 します。

  2. テーブルまたはビューに集計ポリシーを割り当てる場合は、 エンティティキーを定義 します。

最小エンティティ数の指定

CREATE AGGREGATION POLICY で集計ポリシーを作成する構文は、エンティティキーを使用してエンティティレベルのプライバシーを実現する場合でも変わりません。最小グループサイズを指定するには、 AGGREGATION_CONSTRAINT 関数の引数 MIN_GROUP_SIZE を使用します。 エンティティキーを定義する とすぐに、最小グループサイズは、グループ内の記録数に対する要件から、グループ内のエンティティ数に対する要件に変わります。

たとえば、次のコマンドは最小グループサイズが5の集計ポリシーを作成します。ポリシーをテーブルに割り当てるときにエンティティキーを定義する限り、各集約グループには少なくとも5つのエンティティが含まれる必要があります。

CREATE AGGREGATION POLICY my_agg_policy
  AS () RETURNS AGGREGATION_CONSTRAINT ->
  AGGREGATION_CONSTRAINT(MIN_GROUP_SIZE => 5);
Copy

異なる状況下で異なる制限を実施する条件付き集計ポリシーの例を含む、集計ポリシーの作成に関する完全な詳細については、 集計ポリシーを作成する をご参照ください。

エンティティキーの定義

集計ポリシーをテーブルまたは表示に割り当てるときに、テーブルのエンティティキーを定義します。エンティティキーの定義は、 新規テーブルまたはビュー の作成時、または ビュー の既存のテーブルの更新時に行うことができます。

既存のテーブルや表示に対してエンティティキーを定義する

ALTER TABLE ... SET AGGREGATION POLICY コマンドまたは ALTER VIEW ... SET AGGREGATION POLICY コマンドを実行して集計ポリシーを割り当てる場合は、ENTITY KEY 句を使用して、テーブルまたは表示内のどの列にエンティティの識別子属性(つまり、エンティティキー)が含まれるかを指定します。

たとえば、テーブル viewership_log に集計ポリシー my_agg_policy を割り当てながらエンティティキーを作成するには、次のように実行します。

ALTER TABLE viewership_log
  SET AGGREGATION POLICY my_agg_policy
  ENTITY KEY (first_name,last_name);
Copy

first_namelast_name はエンティティキーなので、集計ポリシーは first_name = joelast_name = peterbilt が同じエンティティに属するすべての行を決定できます。

既存のテーブルやビューに対する複数のエンティティキーの定義

既存のテーブルに複数のエンティティキーを定義するには、複数の呼び出しで新しいキーを追加するか、1回の呼び出しで複数のキーを追加します。テーブルでのキーの定義は追加になるため、以前に定義したキーを上書きしたり削除したりすることはありません。

2回の呼び出しで2つのエンティティキーを追加します。 最初のキーは2つの列で構成されます。

ALTER TABLE transactions ADD AGGREGATION POLICY ap ENTITY KEY (user_id, user_email);
ALTER TABLE transactions ADD AGGREGATION POLICY ap ENTITY KEY (vendor_id);
Copy

1回の呼び出しで2つのエンティティキーを追加します。

ALTER TABLE transactions ADD AGGREGATION POLICY ap ENTITY KEY (user_id) ENTITY KEY (vendor_id);
Copy

新しいテーブルとビューのエンティティキーの定義

CREATE TABLE ... WITH AGGREGATION POLICY コマンドまたは CREATE VIEW ... WITH AGGREGATION POLICY コマンドを実行して集計ポリシーを割り当てる場合は、ENTITY KEY 句を使用して、テーブルまたは表示内のどの列にエンティティの識別属性が含まれるかを指定します。

例えば、集計ポリシーを割り当て、エンティティキーを定義しながら新しいテーブル t1 を作成するには、以下を実行します。

CREATE TABLE t1
  WITH AGGREGATION POLICY my_agg_policy
  ENTITY KEY (first_name,last_name);
Copy

first_namelast_name はエンティティキーなので、集計ポリシーは first_name = joelast_name = peterbilt が同じエンティティに属するすべての行を決定できます。

繰延集計ポリシー

クエリにサブクエリがある場合、Snowflakeは最も内側のクエリにエンティティ集約ポリシーを適用しようとします。そのクエリにGROUP BY句があり、GROUP BY列が集計ポリシーのエンティティキーと一致する場合、その集計ポリシーはそのサブクエリには適用されず、そのサブクエリの親クエリに適用されます。この繰り延べは、ポリシーのエンティティキーに一致するGROUP BY列のセットがないクエリに到達するか、最上位のクエリに到達するまで、連鎖的に続きます。いずれの場合も、集計ポリシーはそのクエリに適用されます。集計ポリシーはクエリチェーンで一度だけ適用されます。

たとえば、エンティティキー (name, zipcode) を持つ集計ポリシー my_agg_policy があるとします。以下の擬似クエリでは、内側のクエリに my_agg_policy のエンティティキーに一致するGROUP BYセットがあるため、ポリシーはその親に繰り延べされます。GROUP BY 列がポリシー列と一致したとしても、トップレベルクエリであるため、ポリシーは親に適用されます。

SELECT age, name, zipcode FROM(                        -- Outermost query: my_agg_policy enforced.
  SELECT name, zipcode FROM T GROUP BY name, zipcode   -- Matches my_agg_policy entity key: my_agg_policy deferred
)
  GROUP BY age, name, zipcode;
Copy

GROUP BY列は、繰り延べをトリガーするためにエンティティキー列のスーパーセットにすることができ、ポリシーはGROUP BY列が一致した場合にのみ繰り延べされます。集計関数では繰り延べはトリガーされません。

各集計ポリシーは、クエリ内のすべてのクエリブロックに個別に適用されます。 セット演算子 (UNIONなど)を通して複数のブロックで構成されるクエリは、各クエリブロックに対して個別に集計ポリシーを評価します。

集計の繰り延べは、次の例で示すように、いくつかの有用な効果があります。

繰り延べの例

(zipcode, email) として定義されるエンティティについて、ユーザーを「定額の消費者」と「高額の消費者」の2タイプのバケットに集約したいとします。繰り延べによって、次の例のように動作させることができます。繰り延べがない場合、内側のクエリはNULLを返します。各グループが1つの (zipcode, email) エンティティで構成され、min_group_size が1より大きい値にセットされると抑制されるためです。

WITH bucketed AS (
  SELECT
    CASE
      WHEN SUM(transaction_amount) BETWEEN 0 AND 100 THEN 'low'
      WHEN SUM(transaction_amount) BETWEEN 101 AND 100000 THEN 'high'
    END AS transaction_bucket,
    zipcode,               -- zipcode and email need not appear in the select list, but this lets us compute entity_count below
    email
  FROM my_transactions
  GROUP BY zipcode, email  -- This would not work if it was only GROUP BY zipcode, since the entity key is (zipcode, email)
)
SELECT
  transaction_bucket,
  COUNT(DISTINCT zipcode, email) AS entity_count
FROM
  bucketed
GROUP BY transaction_bucket;
Copy

複数ポリシーの繰り延べ

テーブルに複数の集計ポリシーがある場合、各集計ポリシーは独立して評価され、場合によっては繰り延べされます。異なるクエリレベルで異なるポリシーが適用される場合、予期しない結果が発生する可能性があるため、1つのテーブルに複数の集計ポリシーがある場合はクエリを設計する際に注意が必要です。

例えば、2つの別々の集計ポリシーを持つテーブルで、ユーザーを高額の消費者と低額の消費者のカテゴリに分けるネストされたクエリを試した場合、次のような問題が発生する可能性があります。

表T:

user_id, vendor_id, zipcode, email,         transaction_amount
   1     1001       90000    a@example.com        100
   1     1001       90000    a@example.com         50
   2     2001       90001    b@example.com         12
   2     2001       90001    b@example.com          5
   3     3001       90002    c@example.com         40

集計ポリシー

  • user_policy: min_group_size = 3、entity key = (user_id)

  • vendor_policy: min_group_size = 2、entity key = (vendor_id)

ユーザーを高額の消費者と低額の消費者に分けるクエリ:

WITH amounts AS (
  SELECT
    user_id,
    IFF(SUM(transaction_amount) > 50, 'high', 'low') AS bucket
  FROM T
  GROUP BY user_id -- user_policy is deferred, but vendor_policy is enforced
)
SELECT COUNT(*) FROM amounts GROUP BY bucket
Copy

予期しない結果:

内側のクエリで vendor_policy が実施されます。各行は user_id でグループ化され、このグループには対応する vendor_id が1つしかありません。このため vendor_policy の最小グループサイズに違反し、3人の異なる顧客が「高額」に属していても、内側のクエリはNULLを返します。

エンティティキーの制約の削除

単一つのエンティティキーの集計ポリシーを削除する場合:

-- Drop agg policy ap associated with entity key user_id
ALTER TABLE transactions DROP AGGREGATION POLICY ap ENTITY KEY (user_id)
Copy

複数のエンティティキーの集計ポリシーを削除する場合、 各ポリシーを個別に削除します。

-- Drop the agg policies associated with two separate keys
ALTER TABLE transactions DROP AGGREGATION POLICY ap ENTITY KEY (user_id)
ALTER TABLE transactions DROP AGGREGATION POLICY ap ENTITY KEY (vendor_id)
Copy

集計ポリシーをそのすべてのエンティティと一緒に削除する場合、 DROPステートメントからENTITY KEYを省略します。

-- Drop agg policy ap from the table entirely
ALTER TABLE transactions DROP AGGREGATION POLICY ap
Copy

制限事項

複数のエンティティキーまたは集約ポリシーが定義されているテーブルを操作する場合は、以下の制限が適用されます。

  • エンティティキーは、最大1つのポリシーに関連付けることができます。すでにポリシーにマッピングされているエンティティキーに別のポリシーを割り当てようとするとエラーになります。

  • ポリシーは、行レベルのプライバシーとエンティティレベルのプライバシーの両方に使用することはできません。

  • 行レベルのプライバシーに使用できるポリシーは1つまでです。行レベルの集計ポリシーとして別のポリシーを割り当てようとするとエラーになります。

集計制約のあるテーブルのクエリ

エンティティキーを持つ集計制約付きテーブルのクエリの要件は、エンティティキーを持たないテーブルのクエリと同じです。これらの要件に適合するクエリの種類については、 クエリの要件 をご参照ください。