隐私域简介¶
在 Snowflake 中的差分隐私 中,隐私域 定义了列中可能的值,类似于数学域。隐私域可以是一个具有最小值和最大值的值范围,也可以是值的枚举列表。
隐私域是 Snowflake 用于计算为保护隐私而必须添加的 噪声 的一个因素。正因如此,大多数字段均应具有一个有限隐私域,否则就会增加无限的噪声量。默认情况下,不带隐私域的字段会被假定为具有无限域。
哪些列需要隐私域?¶
除 COUNT 函数外,查询不能对列进行汇总,除非该列有隐私域。同样,除非列有隐私域,否则查询不能在 GROUP BY 子句中使用该列。例如,下面示例中的 score
和 age
列都必须有隐私域。
SELECT AVG(age) FROM t1
GROUP BY score;
df.group_by("score").agg(f.mean("age").as_("mean_age")).show()
这些要求不适用于子查询。例如,在下面的查询中,mean_age
列必须有隐私域,但尽管用于汇总,score
和 age
列并没有隐私域。
SELECT AVG(mean_age)
FROM (SELECT AVG(age) AS mean_age FROM t1 GROUP BY score)
WHERE mean_age >= 20 AND mean_age <= 80;
df.group_by("score").agg(f.mean("age").as_("mean_age")) \
.where((f.col("mean_age") >= 20) & (f.col("mean_age") <= 80)) \
.select(f.mean("mean_age")).show()
定义隐私域¶
管理员和运行查询的分析师均可为列定义隐私域,但他们定义的方式有所不同:
管理员使用 CREATE TABLE 和 ALTER TABLE 命令为列设置隐私域。数据提供商的管理员会首先设置隐私域,然后才允许分析人员进行访问。在某些情况下,分析师的管理员可能还需要在与数据提供商的受保护表相联接的表上设置隐私域。如果您是需要设置隐私域的管理员,请参阅 作为管理员使用隐私域。
分析师使用筛选器和列转换等查询元素来创建查询,从而隐式指定隐私域。这些隐私域可以为没有隐私域的列指定,也可以缩小数据提供商设置的隐私域范围。如果分析师需要指定或缩小隐私域,请参阅 作为分析师在隐私域中工作。
隐私域之间的交互¶
一个查询可能涉及到多个隐私域。同一列上可以有管理员指定的隐私域和分析师指定的隐私域。另外,查询可在两个表中都有隐私域的列上联接两个表。
Snowflake 会评估所有隐私域,并计算出查询期间要使用的隐私域。如需了解如何确定查询时间隐私域,请参阅:
管理员指定的隐私域与分析师指定的隐私域之间的交互¶
分析师使用查询元素隐式为列指定隐私域。例如,基于某一列进行筛选,就会为其定义一个隐私域。分析师指定的隐私域只在查询期间存在,不会改变管理员为列设置的隐私域。
分析师指定的隐私域可以缩小管理员指定的隐私域,但永远无法扩大该隐私域。查询时间隐私域是查询指定的隐私域与管理员设置的隐私域之间的交集。例如,如果数据提供商将隐私域设置为范围 (5, 15),而查询使用筛选器将隐私域指定为范围 (0, 10),那么有效的查询时间隐私域就是 (5, 10)。
同样,如果管理员将隐私域设置为列表 ( 'blue', 'yellow' ),而查询使用筛选器指定的隐私域为 ( 'orange', 'blue'),则查询时的隐私域为 ( 'blue' )。
隐私域与联接¶
当分析师在两个表中都有隐私域的列上联接两个表时,联接类型决定了查询时间隐私域。在查询过程中,有效的隐私域可以是两个隐私域的交集、两个隐私域的并集,或者只是其中一个隐私域。
在下表中,domainL
指的是左表中联接列上的隐私域,domainR
指的是右表中联接列上的隐私域。
联接类型 |
查询时间隐私域 |
---|---|
INNER |
|
OUTER |
|
LEFT |
|
RIGHT |
|
LEFT SEMI |
|
LEFT ANTI |
|
例如,假设 t1
中的 day
列的隐私域为 (1, 100),而 t2
中的 day
列的隐私域为 (0, 90)。当分析师在 day
上联接 t1
和 t2
时,查询时间隐私域为 (1, 90),即两个隐私域的交集。
隐私域外的值¶
隐私域定义的是列中 可能 的值,而不一定是 实际 值。下面汇总了未包含在隐私域列表或范围中的值的情况。
- 字符串
在字符串列中,隐私域以外的值在查询期间始终被视为 NULL。不论是管理员指定的隐私域、分析师指定的隐私域还是隐私域的交集,情况都是如此。
例如,假设数据提供商在
state
列上设置了 ('california'
,'oregon'
) 的隐私域,分析师编写的查询将state
列筛选到 ('nevada'
,'oregon'
)。如果查询在 GROUP BY 子句中使用state
列,则结果包含两个组:OREGON
和NULL
。NULL
组包括state
列的值并非OREGON
的所有记录,以及state
列的值字面量是NULL
的记录。
- 数值、日期和时间
对于在隐私域范围以外的数值、日期或时间值,Snowflake 会根据隐私域由管理员还是分析师定义而采取不同的处理方式。
- 管理员指定:
如果数据提供商定义了一个包含列实际值子集的范围隐私域,隐私域之外的值会被 限制,也就是说,它们会被视为域内最接近的值(最小值或最大值)予以处理。例如,如果列的隐私域由 1-100 之间的整数构成,那么在计算汇总时,实际值为 105 的记录将视同值为 100 处理。分析师无法访问隐私域以外的值。
如果 联接两个受隐私保护的表 导致隐私域交叉,查询时间隐私域之外的值会被限制。
- 分析师指定:
当分析师为没有隐私域的列指定隐私域,或者缩小管理员指定的隐私域时,查询本身会决定如何处理隐私域以外的值。
中间查询元素如何影响隐私域¶
查询的编写方式会影响到隐私域的范围是否发生变化,甚至会影响到列上是否仍然存在隐私域。本节将帮您了解查询的中间部分(即最终聚合之前的部分)如何影响列的隐私域。
- 添加新列
如果查询在现有列的基础上添加了新列,则在原有列上指定或缩小隐私域对新列均无影响。
在下方示例中,假设数据提供商将
score
列上的隐私域定义为 0 到 100 之间的范围。当查询指定score
的隐私域为 1 和 2 之间的范围时,对score_derived
列的隐私域没有影响。
SELECT AVG(score_derived)
FROM (SELECT score, score_derived FROM t1 WHERE score <= 2);
df.with_column("score_derived", f.col("score")) \
.where((f.col("score") >= 1) & \
(f.col("score") <= 2)) \
.select(f.mean("score_derived")).show()
例如,输出可能是:
--------------------------
|"avg(""SCORE_DERIVED"")"|
--------------------------
|31.8196209349 |
--------------------------
- 在中间汇总中使用 GROUP BY 子句
对于查询的中间部分,在汇总列时使用 GROUP BY 子句可移除列中的隐私域。因此,如果在查询的最终汇总中使用该列,则需要为其指定新的隐私域。
在下面的示例中,初始汇总会移除
score
列上设置的任何隐私域。该查询之所以成功,只是因为它在最终汇总之前为列别名设置了隐私域。
SELECT AVG(num_scores)
FROM (SELECT COUNT(score) AS num_scores
FROM t1
GROUP BY age)
WHERE num_scores >= 0 AND num_scores <= 100;
df.group_by("age").agg(f.count("score").as_("num_scores")) \
.where((f.col("num_scores") >= 0) & (f.col("num_scores") <= 100)) \
.select(f.mean("num_scores")).show()