分析ルールを使用してデータアクセスを制限する

このドキュメントでは、GoogleSQL for BigQuery の分析ルールに関する一般的な情報を提供します。

分析ルールとは

分析ルールは、データ共有の条件を適用します。BigQuery では、データ クリーンルームを使用するか、分析ルールを直接ビューに適用することで、分析ルールをビューに適用できます。分析ルールが適用された場合、そのビューをクエリするすべてのユーザーは、そのビューに対する分析ルールに従う必要があります。分析ルールの条件を満たすと、分析ルールを満たす出力が生成されます。クエリが分析ルールの条件を満たしていない場合は、エラーが発生します。

サポートされている分析ルール

次の分析ルールがサポートされています。

  • 集計しきい値の分析ルール: データセットに存在する必要がある個々のエンティティを最小数にします。このルールは、ステートメントまたはデータ クリーンルームを使用してビューに適用します。
  • 差分プライバシーの分析ルール: プライバシー バジェットを適用します。データが差分プライバシーで保護されている場合、サブスクライバーに公開されるデータが制限されます。このルールは、ステートメントまたはデータ クリーンルームを使用してビューに適用します。
  • 結合制限の分析ルール: 特定の列で使用できる結合の種類を制限します。結合は必ずしもクエリに存在する必要はありません。特定の列をブロックすることもできます。集計しきい値または差分プライバシーの分析ルールに含めることができます。このルールは、ステートメントまたはデータ クリーンルームを使用してビューに適用します。
  • リスト重複の分析ルール: 結合制限の分析ルールに似ていますが、他の分析ルールで使用することはできません。このルールは、データ クリーンルームを使用してビューに適用します。

集計しきい値の分析ルール

集計しきい値の分析ルールでは、データセットに存在する必要がある個々のエンティティが最小限になるため、そのデータセットの統計情報がクエリの結果に含まれます。

集計しきい値の分析ルールを適用すると、集計しきい値を確実に満たしながら、ディメンション間でデータがグループ化されます。各グループの個別のプライバシー ユニットの数(プライバシー ユニット列で表される)をカウントし、個別のプライバシー ユニット数が集計しきい値を満たすグループのみを出力します。

この分析ルールを含むビューには、結合制限の分析ルールを含めることもできます。

ビューに集計しきい値の分析ルールを定義する

ビューの集計しきい値の分析ルールは、データ クリーンルームで定義するか、次のステートメントで定義します。

CREATE OR REPLACE VIEW VIEW_NAME
  OPTIONS (
    privacy_policy= '{
      "aggregation_threshold_policy": {
        "threshold" : THRESHOLD,
        "privacy_unit_column": "PRIVACY_UNIT_COLUMN"
      }
    }'
  )
  AS QUERY;

次の値を置き換えます。

  • VIEW_NAME: ビューのパスと名前。
  • THRESHOLD: クエリ結果の各行の出力に必要な個別のプライバシー ユニットの最小数。候補の行がこのしきい値を満たしていない場合、その行はクエリ結果から除外されます。
  • PRIVACY_UNIT_COLUMN: プライバシー ユニット列を表します。プライバシー ユニット列は、プライバシー ユニットの固有識別子です。プライバシー ユニットは、保護されている一連のデータ内のエンティティを表すプライバシー ユニット列の値です。

    使用できるプライバシー ユニット列は 1 つだけです。プライバシー ユニット列のデータ型は Groupable にする必要があります。

    プライバシー ユニット列の値をクエリで直接射影することはできません。この列のデータを集計するには、分析ルールでサポートされている集計関数を使用する必要があります。

  • QUERY: ビューのクエリ。

次の例では、集計しきい値の分析ルールを作成しています。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"aggregation_threshold_policy": {"threshold": 3, "privacy_unit_column": "last_name"}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

CREATE VIEWprivacy_policy 構文を確認するには、CREATE VIEWOPTIONS リストをご覧ください。

ビューの集計しきい値の分析ルールを更新する

ビューの集計しきい値の分析ルールは、データ クリーンルームで変更するか、次のステートメントで変更できます。

ALTER VIEW VIEW_NAME
SET OPTIONS (
  privacy_policy= '{
    "aggregation_threshold_policy": {
      "threshold" : THRESHOLD,
      "privacy_unit_column": "PRIVACY_UNIT_COLUMN"
    }
  }'
)

次の値を置き換えます。

  • VIEW_NAME: ビューのパスと名前。
  • THRESHOLD: クエリ結果の各行の出力に必要な個別のプライバシー ユニットの最小数。候補の行がこのしきい値を満たしていない場合、その行はクエリ結果から除外されます。
  • PRIVACY_UNIT_COLUMN: プライバシー ユニット列を表します。プライバシー ユニット列は、プライバシー ユニットの固有識別子です。プライバシー ユニットは、保護されている一連のデータ内のエンティティを表すプライバシー ユニット列の値です。

    使用できるプライバシー ユニット列は 1 つだけです。プライバシー ユニット列のデータ型は Groupable にする必要があります。

    プライバシー ユニット列の値をクエリで直接射影することはできません。この列のデータを集計するには、分析ルールでサポートされている集計関数を使用する必要があります。

次の例では、集計しきい値の分析ルールを更新しています。

ALTER VIEW mydataset.ExamView
SET OPTIONS (
  privacy_policy= '{"aggregation_threshold_policy": {"threshold": 50, "privacy_unit_column": "last_name"}}'
);

ALTER VIEWprivacy_policy 構文を確認するには、ALTER VIEW SET OPTIONSOPTIONS リストをご覧ください。

集計しきい値の分析ルールが適用されたビューをクエリする

集計しきい値の分析ルールを含むビューは、AGGREGATION_THRESHOLD 句でクエリできます。クエリには集計関数を含める必要があります。このクエリで使用できるのは、分析ルールでサポートされている集計関数だけです。

次の例では、集計しきい値の分析ルールを含むビューをクエリしています。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"aggregation_threshold_policy": {"threshold": 3, "privacy_unit_column": "last_name"}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

-- Query an analysis–rule enforced view called ExamView.
SELECT WITH AGGREGATION_THRESHOLD
  test_id, COUNT(DISTINCT last_name) AS student_count
FROM mydataset.ExamView
GROUP BY test_id;

/*---------+---------------*
 | test_id | student_count |
 +---------+---------------+
 | P91     | 3             |
 | U25     | 4             |
 *---------+---------------*/

AGGREGATION_THRESHOLD 句のその他の例については、AGGREGATION_THRESHOLDをご覧ください。

差分プライバシーの分析ルール

差分プライバシーの分析ルールは、プライバシー バジェットを適用して、差分プライバシーで保護されているデータがサブスクライバーに公開される範囲を制限します。プライバシー バジェットにより、すべてのクエリのイプシロンまたはデルタの合計値がイプシロンまたはデータの合計値に達すると、サブスクライバーは共有データをクエリできなくなります。この分析ルールはビューで使用できます。この分析ルールを含むビューには、結合制限の分析ルールを含めることもできます。

ビューに差分プライバシーの分析ルールを定義する

ビューの差分プライバシーの分析ルールは、データ クリーンルームで定義するか、次のステートメントで定義できます。

CREATE OR REPLACE VIEW VIEW_NAME
  OPTIONS (
    privacy_policy= '{
      "differential_privacy_policy": {
        "privacy_unit_column": "PRIVACY_UNIT_COLUMN",
        "max_epsilon_per_query": MAX_EPSILON_PER_QUERY,
        "epsilon_budget": EPSILON_BUDGET,
        "delta_per_query": DELTA_PER_QUERY,
        "delta_budget": DELTA_BUDGET,
        "max_groups_contributed": MAX_GROUPS_CONTRIBUTED
      }
    }'
  )
  AS QUERY;

次の値を置き換えます。

  • PRIVACY_UNIT_COLUMN: プライバシーの分析ルールで保護されているデータセット内のエンティティを識別する。この値は JSON 文字列です。
  • MAX_EPSILON_PER_QUERY: クエリあたりのプライバシー保証の強度を決定し、単一クエリによってイプシロンの合計数に達することを防ぎます。この値は、0.0011e+15 の JSON 数値です。
  • EPSILON_BUDGET: 全体的なプライバシー保証の強度を表すイプシロンの予算。これは、ビューのすべての差分プライベート クエリに使用されます。この値は 0.0011e+15 の JSON 数値で、MAX_EPSILON_PER_QUERY より大きくする必要があります。
  • DELTA_PER_QUERY: イプシロンの合計数によって決定される、保証を超えるクエリあたりのプライバシー損失の最大確率。単一クエリによってデルタの合計に達しないようにします。この値は、1e-151 の JSON 数値です。
  • DELTA_BUDGET: デルタの予算。イプシロンの合計数によって決定される、保証を超える全体的なプライバシー損失の最大確率を表します。これは、ビューのすべての差分プライベート クエリに使用されます。この値は 1e-151000 の JSON 数値で、DELTA_PER_QUERY より大きくする必要があります。
  • MAX_GROUPS_CONTRIBUTED: 省略可。プライバシー ユニット列のエンティティが関係するグループ数を制限します。この値は 0 または正の JSON 整数にしてください
  • QUERY: ビューのクエリ。

次の例では、差分プライバシーの分析ルールを作成しています。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"differential_privacy_policy": {"privacy_unit_column": "last_name", "max_epsilon_per_query": 10.01, "epsilon_budget": 1000.0, "delta_per_query": 0.01, "delta_budget": 1000.0, "max_groups_contributed": 2}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

-- Epsilon parameters are set very high due to the small dataset.
-- In practice, epsilon should be much smaller.

CREATE VIEWprivacy_policy 構文を確認するには、CREATE VIEWOPTIONS リストをご覧ください。

ビューの差分プライバシーの分析ルールを更新する

ビューの差分プライバシーの分析ルールは、データ クリーンルームで変更するか、次のステートメントで変更できます。

ALTER VIEW VIEW_NAME
SET OPTIONS (
  privacy_policy= '{
    "differential_privacy_policy": {
      "privacy_unit_column": "PRIVACY_UNIT_COLUMN",
      "max_epsilon_per_query": MAX_EPSILON_PER_QUERY,
      "epsilon_budget": EPSILON_BUDGET,
      "delta_per_query": DELTA_PER_QUERY,
      "delta_budget": DELTA_BUDGET,
      "max_groups_contributed": MAX_GROUPS_CONTRIBUTED
    }
  }'
)

次の値を置き換えます。

  • PRIVACY_UNIT_COLUMN: プライバシーの分析ルールで保護されているデータセット内のエンティティを識別する。この値は JSON 文字列です。
  • MAX_EPSILON_PER_QUERY: クエリあたりのプライバシー保証の強度を決定し、単一クエリによってイプシロンの合計数に達することを防ぎます。この値は、0.0011e+15 の JSON 数値です。
  • EPSILON_BUDGET: 全体的なプライバシー保証の強度を表すイプシロンの予算。これは、ビューのすべての差分プライベート クエリに使用されます。この値は 0.0011e+15 の JSON 数値で、MAX_EPSILON_PER_QUERY より大きくする必要があります。
  • DELTA_PER_QUERY: イプシロンの合計数によって決定される、保証を超えるクエリあたりのプライバシー損失の最大確率。単一クエリによってデルタの合計に達しないようにします。この値は、1e-151 の JSON 数値です。
  • DELTA_BUDGET: デルタの予算。イプシロンの合計数によって決定される、保証を超える全体的なプライバシー損失の最大確率を表します。これは、ビューのすべての差分プライベート クエリに使用されます。この値は 1e-151000 の JSON 数値で、DELTA_PER_QUERY より大きくする必要があります。
  • MAX_GROUPS_CONTRIBUTED: 省略可。プライバシー ユニット列のエンティティが関係するグループ数を制限します。この値は 0 または正の JSON 整数にしてください

次の例では、差分プライバシーの分析ルールを更新しています。

ALTER VIEW mydataset.ExamView
SET OPTIONS(
  privacy_policy= '{"differential_privacy_policy": {"privacy_unit_column": "last_name", "max_epsilon_per_query": 0.01, "epsilon_budget": 1000.0, "delta_per_query": 0.005, "delta_budget": 1000.0, "max_groups_contributed": 2}}'
);

-- Epsilon parameters are set very high due to the small dataset.
-- In practice, epsilon should be much smaller.

ALTER VIEWprivacy_policy 構文を確認するには、ALTER VIEW SET OPTIONSOPTIONS リストをご覧ください。

差分プライバシーの分析ルールが適用されているビューをクエリする

差分プライバシーの分析ルールを含むビューは、DIFFERENTIAL_PRIVACY 句でクエリできます。DIFFERENTIAL_PRIVACY 句の構文とその他の例については、DIFFERENTIAL_PRIVACYをご覧ください。

差分プライベート クエリが実行されるようにする

分析ルールが適用されたビューに差分プライバシー クエリを作成し、クエリが実行されるようにします。

たとえば、次のクエリでは、epsilondeltamax_groups_contributed がすべて ExamView の差分分析ルールの条件を満たしているため、差分プライバシーのデータが ExamView から正常に返されます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"differential_privacy_policy": {"privacy_unit_column": "last_name", "max_epsilon_per_query": 1000.01, "epsilon_budget": 1000.0, "delta_per_query": 0.01, "delta_budget": 1000.0, "max_groups_contributed": 2}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

ビューを作成したら、少し待ってから、ビューが作成されたことを確認して、次のクエリを実行します。

-- Query an analysis–rule enforced view called ExamView.
SELECT
  WITH DIFFERENTIAL_PRIVACY
    OPTIONS(epsilon=10, delta=.01, max_groups_contributed=2, privacy_unit_column=last_name)
    test_id,
    AVG(test_score, contribution_bounds_per_group => (0,100)) AS average_test_score
FROM mydataset.ExamView
GROUP BY test_id;

-- These results will change each time you run the query.
-- Smaller aggregations might be removed.
/*---------+--------------------*
 | test_id | average_test_score |
 +---------+--------------------+
 | P91     | ???                |
 | U25     | ???                |
 *---------+--------------------*/

-- Epsilon parameters are set very high due to the small dataset.
-- In practice, epsilon should be much smaller.

範囲外のイプシロンのあるクエリをブロックする

イプシロンはノイズの追加や削除に使用できます。イプシロンを大きくすると、ノイズが追加されなくなります。差分プライバシー クエリのノイズを最小限に抑えるには、差分プライバシーの分析ルールの max_epsilon_per_query の値に注意してください。

たとえば、次のクエリでは、DIFFERENTIAL_PRIVACY 句の epsilonExamViewmax_epsilon_per_query よりも大きいため、エラーでクエリがブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"differential_privacy_policy": {"privacy_unit_column": "last_name", "max_epsilon_per_query": 10.01, "epsilon_budget": 1000.0, "delta_per_query": 0.01, "delta_budget": 1000.0, "max_groups_contributed": 2}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

ビューを作成したら、しばらく待ってから、次のクエリを実行します。

-- Error: epsilon is out of bounds.
SELECT
  WITH DIFFERENTIAL_PRIVACY
    OPTIONS(epsilon=1e20, delta=.01, max_groups_contributed=2, privacy_unit_column=last_name)
    test_id,
    AVG(test_score, contribution_bounds_per_group => (0,100)) AS average_test_score
FROM mydataset.ExamView
GROUP BY test_id;

-- Epsilon parameters are set very high due to the small dataset.
-- In practice, epsilon should be much smaller.

特定のデルタ量のないクエリをブロックする

デルタは、データが誤って漏洩する可能性があるかどうかを判断するしきい値です。デルタが小さいほどしきい値は高くなり、デルタが大きいほどしきい値は低くなります。差分プライバシー クエリに特定のしきい値を設定するには、差分プライバシーの分析ルールで delta_per_query 設定を更新します。

たとえば、次のクエリでは、DIFFERENTIAL_PRIVACY 句の deltaExamViewdelta_per_query と一致しないため、エラーでクエリがブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"differential_privacy_policy": {"privacy_unit_column": "last_name", "max_epsilon_per_query": 10.01, "epsilon_budget": 1000.0, "delta_per_query": 0.01, "delta_budget": 1000.0, "max_groups_contributed": 2}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

ビューを作成したら、しばらく待ってから、次のクエリを実行します。

-- Error: delta in query does not match delta_per_query.
SELECT
  WITH DIFFERENTIAL_PRIVACY
    OPTIONS(epsilon=10, delta=.02, max_groups_contributed=2, privacy_unit_column=last_name)
    test_id,
    AVG(test_score, contribution_bounds_per_group => (0,100)) AS average_test_score
FROM mydataset.ExamView
GROUP BY test_id;

-- Epsilon parameters are set very high due to the small dataset.
-- In practice, epsilon should be much smaller.

イプシロン予算を超えたクエリをブロックする

イプシロンはノイズの追加や削除に使用できます。イプシロンが小さいとノイズが増え、イプシロンが大きいとノイズが減ります。ノイズが多い場合でも、同じデータに対して複数のクエリを実行すると、最終的にはノイズのないデータが明らかになる可能性があります。これを防ぐには、イプシロンの予算を作成します。イプシロンの予算を追加する場合は、ビューの差分プライバシーの分析ルールで epsilon_budget の値を確認します。

次のクエリを 3 回実行します。3 回目は、使用されるイプシロンの合計が 30 であるにもかかわらず、ExamViewepsilon_budget25.6 のみを許可しているため、クエリはブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"differential_privacy_policy": {"privacy_unit_column": "last_name", "max_epsilon_per_query": 10.01, "epsilon_budget": 25.6, "delta_per_query": 0.01, "delta_budget": 1000.0, "max_groups_contributed": 2}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

ビューを作成したら、少し待ってから、次のクエリを 3 回実行します。

-- Error after three query runs: epsilon budget exceeded
SELECT
  WITH DIFFERENTIAL_PRIVACY
    OPTIONS(epsilon=10, delta=.01, max_groups_contributed=2, privacy_unit_column=last_name)
    test_id,
    AVG(test_score, contribution_bounds_per_group => (0,100)) AS average_test_score
FROM mydataset.ExamView
GROUP BY test_id;

-- Epsilon parameters are set very high due to the small dataset.
-- In practice, epsilon should be much smaller.

デルタ予算を超えたクエリをブロックする

デルタは、データが誤って漏洩する可能性があるかどうかを判断するしきい値です。デルタが小さいほどしきい値は高くなり、デルタが大きいほどしきい値は低くなります。しきい値が高くても、同じデータに対する複数のクエリにより、差分プライバシーで保護されたデータが公開される可能性があります。これを防ぐには、デルタの予算を作成します。デルタの予算を追加する場合は、ビューの差分プライバシーの分析ルールで delta_budget の値を確認します。

次のクエリを 7 回実行します。7 回目は、使用されるデルタの合計数が 0.7 であるにもかかわらず、ExamViewdelta_budget0.6 のみを許可しているため、クエリはブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"differential_privacy_policy": {"privacy_unit_column": "last_name", "max_epsilon_per_query": 10.01, "epsilon_budget": 0.2, "delta_per_query": 0.01, "delta_budget": 0.6, "max_groups_contributed": 2}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

ビューを作成したら、少し待ってから、次のクエリを 7 回実行します。

-- Error after seven query runs: epsilon budget exceeded
SELECT
  WITH DIFFERENTIAL_PRIVACY
    OPTIONS(epsilon=10, delta=.01, max_groups_contributed=2, privacy_unit_column=last_name)
    test_id,
    AVG(test_score, contribution_bounds_per_group => (0,100)) AS average_test_score
FROM mydataset.ExamView
GROUP BY test_id;

-- Epsilon parameters are set very high due to the small dataset.
-- In practice, epsilon should be much smaller.

グループ投稿を過度に許可するクエリをブロックする

差分プライバシー クエリで、各エンティティが参加できるグループの数を制限できます。差分プライバシー クエリで各エンティティが関与できるグループの数を制限する場合は、差分プライバシーの分析ルールの max_groups_contributed の値に注意してください。

たとえば、次のクエリでは、DIFFERENTIAL_PRIVACY 句の max_groups_contributedExamViewmax_groups_contributed よりも大きいため、エラーでクエリがブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"differential_privacy_policy": {"privacy_unit_column": "last_name", "max_epsilon_per_query": 10.01, "epsilon_budget": 1000.0, "delta_per_query": 0.01, "delta_budget": 1000.0, "max_groups_contributed": 2}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

ビューを作成したら、しばらく待ってから、次のクエリを実行します。

-- Error: max_groups_contributed is out of bounds.
SELECT
  WITH DIFFERENTIAL_PRIVACY
    OPTIONS(epsilon=10, delta=.02, max_groups_contributed=3, privacy_unit_column=last_name)
    test_id,
    AVG(test_score, contribution_bounds_per_group => (0,100)) AS average_test_score
FROM mydataset.ExamView
GROUP BY test_id;

-- Epsilon parameters are set very high due to the small dataset.
-- In practice, epsilon should be much smaller.

結合制限の分析ルール

結合制限の分析ルールは、ビュー内の特定の列で使用できる結合の種類を制限します。この分析ルールはビューで使用できます。 この分析ルールを含むビューには、集計しきい値の分析ルールまたは差分プライバシーの分析ルールを含めることもできます。

ビューに結合制限分析ルールを定義する

ビューの結合制限の分析ルールは、データ クリーンルームで定義するか、次のステートメントで定義できます。

CREATE OR REPLACE VIEW VIEW_NAME
  OPTIONS (
    privacy_policy= '{
      "join_restriction_policy": {
        "join_condition": "JOIN_CONDITION",
        "join_allowed_columns": JOIN_ALLOWED_COLUMNS
      }
    }'
  )
  AS QUERY;

次の値を置き換えます。

  • JOIN_CONDITION: ビューに適用する結合制限のタイプ。次のいずれかの値です。

    • JOIN_NOT_REQUIRED: このビューをクエリするために結合は必要ありません。結合を使用する場合は、join_allowed_columns の列のみを使用できます。

    • JOIN_BLOCKED: このビューは、どの列とも結合できません。この場合、join_allowed_columns を設定しないでください。

    • JOIN_ANY: このビューをクエリするには、join_allowed_columns の列を少なくとも 1 つ結合する必要があります。

    • JOIN_ALL: このビューをクエリするには、join_allowed_columns のすべての列を内部結合で結合する必要があります。

  • JOIN_ALLOWED_COLUMNS: 結合演算の一部となる列。

  • QUERY: ビューのクエリ。

次の例では、結合制限の分析ルールを作成しています。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"join_restriction_policy": {"join_condition": "JOIN_ANY", "join_allowed_columns": ["test_id", "test_score"]}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

結合制限の分析ルールを別の分析ルールで使用する

結合制限の分析ルールは、集計しきい値または差分プライバシーの分析ルールで使用できます。ただし、ビューで別の分析ルールと結合制限を使用した場合、制限を適用した分析ルールを変更することはできません。

次の例では、結合制限の分析ルールと集計しきい値の分析ルールを組み合わせて使用しています。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"join_restriction_policy": {"join_condition": "JOIN_ANY", "join_allowed_columns": ["test_id", "test_score"]}, "aggregation_threshold_policy": {"threshold": 3, "privacy_unit_column": "last_name"}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

ビューの結合制限の分析ルールを更新する

ビューの結合制限の分析ルールは、データ クリーンルームを使用するか、次のステートメントで変更できます。

ALTER VIEW VIEW_NAME
SET OPTIONS (
  privacy_policy= '{
    "join_restriction_policy": {
      "join_condition": "JOIN_CONDITION",
      "join_allowed_columns": JOIN_ALLOWED_COLUMNS
    }
  }'
)

次の値を置き換えます。

  • JOIN_CONDITION: ビューに適用する結合制限のタイプ。次のいずれかの値です。

    • JOIN_NOT_REQUIRED: このビューをクエリするために結合は必要ありません。結合を使用する場合は、join_allowed_columns の列のみを使用できます。

    • JOIN_BLOCKED: このビューは、どの列とも結合できません。この場合、join_allowed_columns を設定しないでください。

    • JOIN_ANY: このビューをクエリするには、join_allowed_columns の列を少なくとも 1 つ結合する必要があります。

    • JOIN_ALL: このビューをクエリするには、join_allowed_columns のすべての列を内部結合で結合する必要があります。

  • JOIN_ALLOWED_COLUMNS: 結合演算の一部となる列。

  • QUERY: ビューのクエリ。

次の例では、結合制限の分析ルールを更新しています。

ALTER VIEW mydataset.ExamView
SET OPTIONS(
  privacy_policy= '{"join_restriction_policy": {"join_condition": "JOIN_ALL", "join_allowed_columns": ["test_id", "test_score"]}}'
);

ALTER VIEWprivacy_policy 構文を確認するには、ALTER VIEW SET OPTIONSOPTIONS リストをご覧ください。

結合制限の分析ルールが適用されたビューをクエリする

結合制限の分析ルールを含むビューに結合オペレーションを実行できます。JOIN 演算の構文を確認するには、結合演算をご覧ください。

結合制限クエリが実行されていることを確認する

結合制限クエリが実行されていることをテストする必要があります。

たとえば、次のクエリでは、結合されたデータが ExamViewStudentTable から正常に返されます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a table called StudentTable.
CREATE TABLE mydataset.StudentTable AS (
  SELECT "Hansen" AS last_name, 510 AS test_score UNION ALL
  SELECT "Wang", 500 UNION ALL
  SELECT "Devi", 580 UNION ALL
  SELECT "Ivanov", 490 UNION ALL
  SELECT "Silva", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"join_restriction_policy": {"join_condition": "JOIN_ANY", "join_allowed_columns": ["test_score"]}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

-- Query the ExamView view.
SELECT *
FROM mydataset.ExamView INNER JOIN mydataset.StudentTable USING (test_score)
GROUP BY test_id;

-- These results will change each time you run the query.
-- Smaller aggregations might be removed.
/*---------+--------------------*
 | test_id | average_test_score |
 +---------+--------------------+
 | P91     | ???                |
 | U25     | ???                |
 *---------+--------------------*/

必要な列がまったくない結合オペレーションをブロックする

結合演算に必要な列が 1 つも含まれていない場合は、結合演算をブロックできます。そのためには、結合制限の分析ルールに次の部分を含めます。

"join_restriction_policy": {
  "join_condition": "JOIN_ANY",
  "join_allowed_columns": ["column_name", ...]
}

たとえば、次のクエリでは、ExamViewStudentTabletest_score 列または test_id 列に対する結合演算が含まれていないため、エラーでブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a table called StudentTable.
CREATE TABLE mydataset.StudentTable AS (
  SELECT "Hansen" AS last_name, 510 AS test_score UNION ALL
  SELECT "Wang", 500 UNION ALL
  SELECT "Devi", 580 UNION ALL
  SELECT "Ivanov", 490 UNION ALL
  SELECT "Silva", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"join_restriction_policy": {"join_condition": "JOIN_ANY", "join_allowed_columns": ["test_score", "test_id"]}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

-- Query the ExamView view.
SELECT *
FROM mydataset.ExamView INNER JOIN mydataset.StudentTable USING (last_name)
GROUP BY test_id;

前のクエリを実行するには、USING 句で last_nametest_score に置き換えます。

結合オペレーションのないクエリをブロックする

クエリに結合演算が含まれている必要がある場合、次の結合制限の分析ルールのいずれかを使用し、結合演算が存在しない場合にクエリをブロックできます。

"join_restriction_policy": {
  "join_condition": "JOIN_NOT_REQUIRED"
}
"join_restriction_policy": {
  "join_condition": "JOIN_NOT_REQUIRED",
  "join_allowed_columns": []
}

たとえば、次のクエリでは、クエリに結合演算がないため、クエリがブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a table called StudentTable.
CREATE TABLE mydataset.StudentTable AS (
  SELECT "Hansen" AS last_name, 510 AS test_score UNION ALL
  SELECT "Wang", 500 UNION ALL
  SELECT "Devi", 580 UNION ALL
  SELECT "Ivanov", 490 UNION ALL
  SELECT "Silva", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"join_restriction_policy": {"join_condition": "JOIN_NOT_REQUIRED"}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

-- Query the ExamView view.
SELECT *
FROM mydataset.ExamView
GROUP BY test_id;

結合演算がなく、必要な列もないクエリをブロックする

クエリに結合演算が含まれ、結合演算に必要な列が 1 つ以上含まれている必要がある場合は、結合制限の分析ルールに次の部分を含めます。

"join_restriction_policy": {
  "join_condition": "JOIN_NOT_REQUIRED",
  "join_allowed_columns": ["column_name", ...]
}

たとえば、次のクエリでは、結合オペレーションに join_allowed_columns 配列の列が含まれていないため、クエリがブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a table called StudentTable.
CREATE TABLE mydataset.StudentTable AS (
  SELECT "Hansen" AS last_name, 510 AS test_score UNION ALL
  SELECT "Wang", 500 UNION ALL
  SELECT "Devi", 580 UNION ALL
  SELECT "Ivanov", 490 UNION ALL
  SELECT "Silva", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"join_restriction_policy": {"join_condition": "JOIN_NOT_REQUIRED", "join_allowed_columns": ["test_score"]}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

-- Query the ExamView view.
SELECT *
FROM mydataset.ExamView INNER JOIN mydataset.StudentTable USING (last_name)
GROUP BY test_id;

前のクエリを実行するには、USING 句で last_nametest_score に置き換えます。

すべての結合オペレーションをブロックする

すべての結合オペレーションをブロックできます。そのためには、結合制限の分析ルールに次の部分のみを含めます。

"join_restriction_policy": {
  "join_condition": "JOIN_BLOCKED",
}

たとえば、次のクエリでは、結合演算があるため、クエリがブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a table called StudentTable.
CREATE TABLE mydataset.StudentTable AS (
  SELECT "Hansen" AS last_name, 510 AS test_score UNION ALL
  SELECT "Wang", 500 UNION ALL
  SELECT "Devi", 580 UNION ALL
  SELECT "Ivanov", 490 UNION ALL
  SELECT "Silva", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"join_restriction_policy": {"join_condition": "JOIN_BLOCKED"}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

-- Query the ExamView view.
SELECT *
FROM mydataset.ExamView INNER JOIN mydataset.StudentTable USING (last_name)
GROUP BY test_id;

前のクエリを実行するには、INNER JOIN オペレーションを削除します。

必要な列が不足している内部結合オペレーションをブロックする

必要な列がすべて含まれていない場合、内部結合オペレーションをブロックできます。そのためには、結合制限の分析ルールに次の部分を含めます。

"join_restriction_policy": {
  "join_condition": "JOIN_ALL",
  "join_allowed_columns": ["column_name", ...]
}

たとえば、次のクエリでは、結合演算に test_score が含まれていないため、エラーでクエリがブロックされます。

-- Create a table called ExamTable.
CREATE TABLE mydataset.ExamTable AS (
  SELECT "Hansen" AS last_name, "P91" AS test_id, 510 AS test_score UNION ALL
  SELECT "Wang", "U25", 500 UNION ALL
  SELECT "Wang", "C83", 520 UNION ALL
  SELECT "Wang", "U25", 460 UNION ALL
  SELECT "Hansen", "C83", 420 UNION ALL
  SELECT "Hansen", "C83", 560 UNION ALL
  SELECT "Devi", "U25", 580 UNION ALL
  SELECT "Devi", "P91", 480 UNION ALL
  SELECT "Ivanov", "U25", 490 UNION ALL
  SELECT "Ivanov", "P91", 540 UNION ALL
  SELECT "Silva", "U25", 550);

-- Create a table called StudentTable.
CREATE TABLE mydataset.StudentTable AS (
  SELECT "Hansen" AS last_name, 510 AS test_score UNION ALL
  SELECT "Wang", 500 UNION ALL
  SELECT "Devi", 580 UNION ALL
  SELECT "Ivanov", 490 UNION ALL
  SELECT "Silva", 550);

-- Create a view that includes ExamTable.
CREATE VIEW mydataset.ExamView
OPTIONS(
  privacy_policy= '{"join_restriction_policy": {"join_condition": "JOIN_ALL", "join_allowed_columns": ["test_score", "last_name"]}}'
)
AS ( SELECT * FROM mydataset.ExamTable );

-- Query the ExamView view.
SELECT *
FROM mydataset.ExamView INNER JOIN mydataset.StudentTable USING (last_name)
GROUP BY test_id;

前のクエリを実行するには、USING (last_name)USING (last_name, test_score) に置き換えます。

リスト重複の分析ルール

特定の列で使用できる結合の種類を制限します。結合はクエリに存在する必要があり、特定の列はブロックできません。データ クリーンルームのビューに対して、リスト重複の分析ルールを定義して更新できます。詳細については、データ クリーンルームを使用して機密データを共有するをご覧ください。

制限事項

分析ルールには次の制限があります。

  • 分析ルールをビューに追加している場合は、集計しきい値の分析ルールと差分の分析ルールを切り替えることはできません。

集計しきい値の分析ルールには、次の制限があります。

  • 集計しきい値分析ルールが適用されているビューに対するクエリでは、サポートされている集計関数のみを使用できます。
  • 集計しきい値の分析ルールをマテリアライズド ビューに追加することはできません。
  • 集計しきい値クエリで集計しきい値の分析ルールが適用されているビューを使用する場合は、両方でプライバシー ユニット列の値が同じである必要があります。
  • 集計しきい値の分析ルールが適用されたビューを集計しきい値クエリで使用する場合は、クエリのしきい値がビューのしきい値以上である必要があります。
  • 集計しきい値の分析ルールが設定されているビューでは、タイムトラベルが無効になっています。

差分プライバシーの分析ルールには、次の制限があります。

  • ビューのプライバシー バジェットがすべて使用されると、そのビューは使用できなくなり、新しいビューを作成する必要があります。

結合制限の分析ルールには次の制限があります。

  • 結合制限の分析ルールで privacy_unit_columnjoin_allowed_column として指定しないと、特定の状況で列を結合できない場合があります。

料金