

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 什么是 AWS Clean Rooms？
<a name="what-is"></a>

AWS Clean Rooms 帮助您和您的合作伙伴对您的集体数据集进行分析和协作，以获得新的见解，而无需互相透露基础数据。 AWS Clean Rooms 是一个安全的协作工作空间，您可以在几分钟内创建自己的干净室，只需几个步骤即可分析您的集体数据集。您可以选择要与之合作的合作伙伴，选择他们的数据集，然后为这些合作伙伴配置隐私增强控件。

借助 AWS Clean Rooms，您可以与成千上万家已经在使用的公司进行协作 AWS。协作不需要将数据移出其他云服务提供商 AWS 或将其加载到其他云服务提供商。当您运行查询或作业时，会从该数据的原始位置 AWS Clean Rooms 读取数据，并应用内置的分析规则来帮助您保持对这些数据的控制。

AWS Clean Rooms 提供您可以配置的内置数据访问控制和审计支持控件。这些控制包括：
+ 用于限制 SQL 查询和提供输出约束的@@ [分析规则](analysis-rules.md)。
+ [加密计算，Clean Rooms用于](crypto-computing.md)保持数据加密，即使在处理查询时也是如此，以遵守严格的数据处理政策。
+ [分析日志](query-logs.md)，用于查看查询和任务 AWS Clean Rooms 并帮助支持审计。
+ [差异隐私](differential-privacy.md)，可防止用户识别尝试。 AWS Clean Rooms 差异隐私是一项完全托管的功能，可通过数学支持的技术和直观的控件来保护用户的隐私，只需几个步骤即可应用这些技术和直观的控件。
+ [AWS Clean Rooms ML](machine-learning.md) 允许双方识别其数据中的相似用户，而无需彼此共享数据。第一方通过其训练数据创建并配置一个相似模型。然后，会将种子数据引入到协作中，以便创建与训练数据类似的相似细分。

以下视频解释了更多相关信息 AWS Clean Rooms。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/0S6icreVCO0/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/0S6icreVCO0)


## 你是首次 AWS Clean Rooms 使用吗？
<a name="first-time-user"></a>

如果您是首次使用 AWS Clean Rooms，我们建议您先阅读以下章节：
+ [如何 AWS Clean Rooms 运作](#how-it-works)
+ [正在访问 AWS Clean Rooms](#accessing-service)
+ [设置 AWS Clean Rooms](setting-up.md)
+ [AWS Clean Rooms 词汇表](glossary.md)

## 如何 AWS Clean Rooms 运作
<a name="how-it-works"></a>

在中 AWS Clean Rooms，您可以创建协作并添加要邀请的人，或者创建成员资格以加入您已被邀请参加的协作。 AWS 账户 然后，您可以链接您的使用案例所需的数据资源：针对事件数据的配置表、针对机器学习建模的配置模型，或针对实体解析的 ID 命名空间。您可以选择创建或批准分析模板，以便事先就协作中要允许的确切查询和任务达成一致。最后，您可以通过在配置的表上运行 SQL 查询或 PySpark 作业、在 ID 映射表中执行实体解析或使用 ML 建模生成相似的受众细分来分析联合数据。

下图显示了 AWS Clean Rooms 工作原理。

![\[解释 AWS Clean Rooms 工作原理的图表\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/images/how-it-works.png)


## 相关服务
<a name="related-services"></a>

### AWS 服务
<a name="related-services-aws"></a>

以下内容与 AWS 服务 以下内容有关 AWS Clean Rooms：
+ **Amazon Athena**

  协作成员可以将他们 AWS Clean Rooms 作为 AWS Glue Data Catalog 视图带入的数据存储在 Amazon Athena 中。有关更多信息，请参阅以下主题：

  有关更多信息，请参阅以下主题：

  [在中为查询准备数据表 AWS Clean Rooms](prepare-data.md)

  [创建已配置表-Amazon Athena 数据源](create-config-table-athena.md)

  [什么是 Amazon Athena？](https://docs.aws.amazon.com/athena/latest/ug/what-is.html) 在*亚马逊 Athena 用户指南*中
+ **CloudFormation**

  在中创建以下资源 CloudFormation：协作、已配置的表、配置的表关联和成员资格

  有关更多信息，请参阅 [使用创建 AWS Clean Rooms 资源 AWS CloudFormation](creating-resources-with-cloudformation.md)。
+ **AWS CloudTrail**

   AWS Clean Rooms 与 CloudTrail 日志配合使用可增强对 AWS 服务 活动的分析。

  有关更多信息，请参阅 [使用记录 AWS Clean Rooms API 调用 AWS CloudTrail](logging-using-cloudtrail.md)。
+ **AWS Entity Resolution 数据匹配服务**

   AWS Clean Rooms 与一起使用 AWS Entity Resolution 数据匹配服务 可执行实体解析。

  有关更多信息，请参阅 [AWS Entity Resolution 数据匹配服务 in AWS Clean Rooms](working-with-entity-resolution.md)。
+ **AWS Glue** 

  协作成员可以根据自己在 Amazon S3 中的数据创建 AWS Glue 表以供在中使用 AWS Clean Rooms。

  有关更多信息，请参阅以下主题：

  [在中为查询准备数据表 AWS Clean Rooms](prepare-data.md)

  《AWS Glue 开发人员指南》**中的 [What is AWS Glue?](https://docs.aws.amazon.com/glue/latest/dg/what-is-glue.html)
+ **Amazon Simple Storage Service（Amazon S3）** 

  协作成员可以将他们带入的 Amazon S3 AWS Clean Rooms 中的数据存储。

  有关更多信息，请参阅以下主题：

  [在中为查询准备数据表 AWS Clean Rooms](prepare-data.md)

  [创建已配置的表-Amazon S3 数据源](create-config-table-s3.md)

  *《Amazon Simple Storage Service 用户指南》*中的[什么是 Amazon S3？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html)
+ **AWS Secrets Manager**

  协作成员可以创建密钥来访问和读取 Snowflake 中存储的数据。

  有关更多信息，请参阅以下主题：

  [创建服务角色以从 Snowflake 读取数据](setting-up-roles.md#create-service-role-third-party)

  [在中为查询准备数据表 AWS Clean Rooms](prepare-data.md)

  *AWS Secrets Manager 用户指南* 中的[什么是 AWS Secrets Manager？](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)

### 第三方服务
<a name="third-party-servies-list"></a>

以下第三方服务与以下内容有关 AWS Clean Rooms：
+ **Snowflake**

  协作成员可以将他们带入 Snowflake 仓库中的数据存储 AWS Clean Rooms 在 Snowflake 仓库中。

  有关更多信息，请参阅以下主题：

  [在中为查询准备数据表 AWS Clean Rooms](prepare-data.md)

  [创建已配置的表 — Snowflake 数据源](create-config-table-snowflake.md)

## 正在访问 AWS Clean Rooms
<a name="accessing-service"></a>

您可以 AWS Clean Rooms 通过以下选项进行访问：
+ 直接通过 AWS Clean Rooms 控制台，网址为[https://console.aws.amazon.com/cleanrooms/](https://console.aws.amazon.com/cleanrooms/)。
+ 通过 AWS Clean Rooms API 以编程方式进行。有关更多信息，请参阅 [https://docs.aws.amazon.com/clean-rooms/latest/apireference/Welcome.html](https://docs.aws.amazon.com/clean-rooms/latest/apireference/Welcome.html)。

## 的定价 AWS Clean Rooms
<a name="pricing"></a>

有关定价信息，请参阅 [AWS Clean Rooms 定价](https://aws.amazon.com/clean-rooms/pricing/)。

**注意**  
对于关联存储在 Snowflake 中的数据的协作成员，每次运行使用存储在这些位置的数据的查询时，他们各自的数据仓库提供商或云提供商都将向您收取数据流出和计算费用。

## 的账单 AWS Clean Rooms
<a name="billing"></a>

AWS Clean Rooms 使协作创建者能够指定哪个成员为协作中的查询或作业计算费用付费。

大多数情况下，[可以查询的成员](glossary.md#glossary-member-who-can-query)和[为查询计算费用付费的成员](glossary.md#glossary-member-paying-for-query-compute)是相同的人。但是，如果可以查询的成员和为查询计算费用付费的成员不同，则当可以查询的成员针对自己的成员身份资源运行查询时，将按支付查询计算费用的成员的成员身份资源计费。

支付查询计算费用的成员在其 CloudTrail 事件历史记录中看不到任何正在运行的查询的事件，因为付款人既不是运行查询的人，也不是运行查询所针对的资源的所有者。但是，对于可以在协作中运行查询的成员运行的所有查询，付款人确实会看到其会员资源上产生的费用。

有关如何创建协作和配置支付查询计算费用的成员的更多信息，请参阅[创建协作](create-collaboration.md)。

# 中的分析规则 AWS Clean Rooms
<a name="analysis-rules"></a>

作为启用表格 AWS Clean Rooms 用于协作分析的一部分，协作成员必须配置*分析规则*。

分析规则是每个数据所有者在配置表上设置的隐私增强控制。分析规则决定了如何分析配置表。

分析规则是对配置表（账户级资源）的账户级控制，并且在关联了配置表的任何协作中强制执行。如果未配置分析规则，则可以将配置表关联到协作，但无法对其进行查询。查询只能引用具有相同分析规则类型的配置表。

要配置分析规则，首先要选择分析类型，然后指定分析规则。在这两个步骤中，您都应考虑要启用的使用案例以及如何保护底层数据。

AWS Clean Rooms 对查询中引用的所有已配置表强制执行更严格的控制。

以下示例演示了限制性控制。

**Example 限制性控制：输出约束**  
+ 协作者 A 对标识符列的输出限制为 100。
+ 协作者 B 对标识符列的输出限制为 150。

  引用两个配置表的聚合查询要求输出行中至少有 150 个不同的标识符值，才能在查询输出中显示。查询输出并没有显示由于输出约束而删除了结果。

**Example 限制性控制：分析模板未获得批准**  
+ 协作者 A 允许在其自定义分析规则中使用带有引用协作者 A 和协作者 B 配置表的查询的分析模板。
+ 协作者 B 不允许使用分析模板。

  由于协作者 B 不允许使用分析模板，因此可以查询的成员无法运行该分析模板。

## 分析规则类型
<a name="summary-table"></a>

有三种类型的分析规则：[聚合](analysis-rules-aggregation.md)、[列表](analysis-rules-list.md)和[自定义](analysis-rules-custom.md)。下表对这些分析规则类型进行了比较。每种类型具有单独的部分，以描述如何指定分析规则。

**注意**  
有一种名为 ID 映射表分析规则的分析规则。但是，此分析规则由管理 AWS Clean Rooms 且无法修改。有关更多信息，请参阅 [ID 映射表分析规则](analysis-rules-id-mapping-table.md)。

以下部分描述了每种分析规则类型支持的使用案例和控制。

### 支持的使用案例
<a name="supported-use-cases"></a>

下表显示了每种分析规则类型支持的使用案例的比较总结。


| 应用场景 | [聚合](analysis-rules-aggregation.md) | [列表](analysis-rules-list.md) | [自定义](analysis-rules-custom.md) | 
| --- | --- | --- | --- | 
| 支持的分析 | 使用 COUNT、SUM 和 AVG 函数按可选维度聚合统计数据的查询  | 输出多个表之间重叠部分的行级列表的查询  | 经过分析模板或分析创建者审核并允许的任何自定义分析  | 
| 常见使用案例 | 细分分析、衡量、归因  | 扩充、细分构建  | 首次接触归因、增量分析、受众发现  | 
| SQL 构造 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules.html)  | 通过 SELECT 命令可使用的大多数 SQL 函数和 SQL 构造 | 
| 子查询和公用表表达式 () CTEs  | 否 | 否 | 是 | 
| 分析模板 | 否 | 否 | 是 | 

### 支持的控制
<a name="supported-controls"></a>

下表显示了每种分析规则类型如何保护底层数据的比较总结。


| 控件 | [聚合](analysis-rules-aggregation.md) | [列表](analysis-rules-list.md) | [自定义](analysis-rules-custom.md) | 
| --- | --- | --- | --- | 
| 控制机制 | 控制如何在查询中使用表中的数据*（例如，允许对列 hashed\$1email 进行 COUNT 和 SUM。）* | 控制如何在查询中使用表中的数据*（例如，仅允许使用 hashed\$1email 列进行联接。）* | 控制允许在表上运行哪些查询*（例如，仅允许在分析模板“自定义查询 1”中定义的查询。）* | 
| 内置隐私增强技术 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules.html)  | 
| 在运行查询之前对其进行审核 | 否 | 否 | 是，正在使用分析模板 | 

有关中提供的分析规则的更多信息 AWS Clean Rooms，请参阅以下主题。
+ [聚合分析规则](analysis-rules-aggregation.md)
+ [列表分析规则](analysis-rules-list.md)
+ [中的自定义分析规则 AWS Clean Rooms](analysis-rules-custom.md)

# 聚合分析规则
<a name="analysis-rules-aggregation"></a>

在中 AWS Clean Rooms，*聚合分析规则*使用可选维度的 COUNT、SUM、 and/or AVG 函数生成聚合统计数据。将聚合分析规则添加到配置表后，可以查询的成员就能在配置表上运行查询。

聚合分析规则支持活动规划、媒体覆盖率、频率测量和归因等使用案例。

支持的查询结构和语法在 [聚合查询结构和语法](#agg-query-structure-syntax) 中定义。

[聚合分析规则 — 查询控制](#agg-query-controls) 中定义的分析规则的参数包括查询控制和查询结果控制。其查询控制包括要求一个配置表至少联接到一个可直接或临时查询的成员所拥有的配置表。此要求可使您确保在您的表及其他人的表的交叉点 (INNER JOIN) 上运行查询。

## 聚合查询结构和语法
<a name="agg-query-structure-syntax"></a>

对具有聚合分析规则的表的查询必须遵循以下语法。

```
--select_aggregate_function_expression
SELECT 
aggregation_function(column_name) [[AS] column_alias ] [, ...]

 --select_grouping_column_expression                        
  [, {column_name|scalar_function(arguments)} [[AS] column_alias ]][, ...]   

--table_expression
FROM table_name [[AS] table_alias ]
  [[INNER] JOIN table_name [[AS] table_alias] ON join_condition] [...]

--where_expression
[WHERE where_condition]          

--group_by_expression                          
[GROUP BY {column_name|scalar_function(arguments)}, ...]]                  

--having_expression
[HAVING having_condition]                               

--order_by_expression    
[ORDER BY {column_name|scalar_function(arguments)} [{ASC|DESC}]] [,...]]
```

下表解释前面语法中列出的每个表达式。


| Expression | 定义 | 示例 | 
| --- | --- | --- | 
| select\$1aggregate\$1function\$1expression |  包含以下表达式的逗号分隔列表： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules-aggregation.html)  `select_aggregate_expression` 中必须至少有一个 `select_aggregation_function_expression`。   |  `SELECT SUM(PRICE), user_segment`  | 
| select\$1aggregation\$1function\$1expression |  应用于一个或多个列的一个或多个支持的聚合函数。只允许将列作为聚合函数的参数。  `select_aggregate_expression` 中必须至少有一个 `select_aggregation_function_expression`。   |  `AVG(PRICE)` `COUNT(DISTINCT user_id)`  | 
| select\$1grouping\$1column\$1expression |  可以包含任何使用以下元素的表达式的表达式： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules-aggregation.html)  `select_aggregate_expression` 可以带或不带 `AS` 参数对列设置别名。有关更多信息，请参阅 [AWS Clean Rooms SQL 参考](https://docs.aws.amazon.com/clean-rooms/latest/sql-reference/sql-reference.html)。   |  `TRUNC(timestampColumn)`  `UPPER(campaignName)`   | 
| table\$1expression |  使用 `join_condition` 连接联接条件表达式的表或表的联接。 `join_condition` 返回布尔值。 `table_expression` 支持： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules-aggregation.html)  |  <pre>FROM consumer_table <br />INNER JOIN provider_table<br />ON<br />consumer_table.identifier1 = provider_table.identifier1<br />AND<br />consumer_table.identifier2 = provider_table.identifier2</pre>  | 
| where\$1expression |  返回布尔值的条件表达式。它可能包括以下内容： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules-aggregation.html) 支持的比较条件是 (`=, >, <, <=, >=, <>, !=, NOT, IN, NOT IN, LIKE, IS NULL, IS NOT NULL`)。 支持的逻辑运算符是 (`AND, OR`)。 `where_expression` 是可选项。  |  `WHERE where_condition` `WHERE price > 100`  `WHERE TRUNC(timestampColumn) = '1/1/2022'`  `WHERE timestampColumn = timestampColumn2 - 14`   | 
| group\$1by\$1expression |  满足 `select_grouping_column_expression` 要求的表达式的逗号分隔列表。  |  `GROUP BY TRUNC(timestampColumn), UPPER(campaignName), segment`  | 
| having\$1expression |  返回布尔值的条件表达式。它们具有应用于单列（例如 `SUM(price)`）的支持聚合函数，并与数值文字进行比较。 支持的比较条件是 (`=, >, <, <=, >=, <>, !=`)。 支持的逻辑运算符是 (`AND, OR`)。 `having_expression` 是可选项。  |  `HAVING SUM(SALES) > 500`  | 
| order\$1by\$1expression |  以逗号分隔的表达式列表，与前面定义的 `select_aggregate_expression` 中定义的要求一致。 `order_by_expression` 是可选项。  `order_by_expression` 允许 `ASC` 和 `DESC` 参数。有关更多信息，请参阅 [AWS Clean Rooms SQL 参考](https://docs.aws.amazon.com/clean-rooms/latest/sql-reference/sql-reference.html)中的 ASC DESC 参数。   |  `ORDER BY SUM(SALES), UPPER(campaignName)`  | 

关于聚合查询的结构和语法，请注意以下几点：
+ 不支持除 SELECT 之外的 SQL 命令。
+ 不支持子查询和通用表格表达式（例如 WITH）。
+ 不支持组合多个查询的运算符（例如 UNION）。
+ TOP、LIMIT 和 OFFSET 参数不受支持。

## 聚合分析规则 — 查询控制
<a name="agg-query-controls"></a>

使用聚合查询控制，您可以控制如何使用表中的列来查询表。例如，您可以控制哪一列用于联接，哪一列可以计数，或者 WHERE 语句中可以使用哪一列。

下面几节解释每种控制。

**Topics**
+ [聚合控制](#agg-functions)
+ [联接控制](#join-controls)
+ [维度控制](#dimension-controls)
+ [标量函数](#scalar-functions)

### 聚合控制
<a name="agg-functions"></a>

通过使用*聚合控制*，您可以定义允许哪些聚合函数以及必须将其应用于哪些列。聚合函数可以在 SELECT、HAVING 和 ORDER BY 表达式中使用。


| 控件 | 定义 | 用法 | 
| --- | --- | --- | 
| aggregateColumns | 允许在聚合函数中使用的已配置表列的列。 |  `aggregateColumns` 可以在 SELECT、HAVING 和 ORDER BY 表达式中的聚合函数中使用。 有些 `aggregateColumns` 也可以归类为 `joinColumn`（稍后定义）。 给定的 `aggregateColumn` 也不能归类为 `dimensionColumn`（稍后定义）。  | 
| function | 允许在 aggregateColumns 上使用的 COUNT、SUM 和 AVG 函数。 |  `function` 可以应用于与之关联的 `aggregateColumns`。  | 

### 联接控制
<a name="join-controls"></a>

`JOIN` 子句用于根据两个或多个表中的相关列合并两个或多个表中的行。

您可以使用*联接控件*来控制如何将您的表连接到中的其他表`table_expression`。 AWS Clean Rooms 仅支持INNERJOIN。 INNERJOIN语句只能使用在分析规则`joinColumn`中明确归类为 a 的列，但要遵守您定义的控件。

INNER JOIN 必须对您的已配置表中的 `joinColumn` 和协作中另一个已配置表中的 `joinColumn` 进行操作。您可以决定表中的哪些列可以用作 `joinColumn`。

ON 子句中的每个匹配条件都要求在两列之间使用相等比较条件 (`=`)。

ON 子句中的多个匹配条件可以是：
+ 使用 `AND` 逻辑运算符组合
+ 使用 `OR` 逻辑运算符分隔

**注意**  
所有 JOIN 匹配条件都必须与 JOIN 两侧各一条记录匹配。所有由 `OR` 或 `AND` 逻辑运算符连接的条件也必须遵守此要求。

以下是使用 `AND` 逻辑运算符的查询示例。

```
SELECT some_col, other_col 
FROM table1 
    JOIN table2 
    ON table1.id = table2.id AND table1.name = table2.name
```

以下是使用 `OR` 逻辑运算符的查询示例。

```
SELECT some_col, other_col 
FROM table1 
    JOIN table2 
    ON table1.id = table2.id OR table1.name = table2.name
```


| 控件 | 定义 | 用法 | 
| --- | --- | --- | 
| joinColumns | 您希望允许可以查询的成员在 INNER JOIN 语句中使用的列（如果有）。 |  特定的 `joinColumn` 也可以归类为 `aggregateColumn`（参阅[聚合控制](#agg-functions)）。 同一列不能同时用作 `joinColumn` 和 `dimensionColumns`（见下文）。 除非它也被归类为 `aggregateColumn`，否则除了 INNER JOIN 之外，查询的其他部分都不能使用 `joinColumn`。  | 
| joinRequired | 控制您是否要求与可以查询的成员的已配置表进行 INNER JOIN。 |  如果启用了此参数，则要求 INNER JOIN。如果未启用此参数，则 INNER JOIN 是可选的。 假设您启用了此参数，则可以查询的成员需要在 INNER JOIN 中包含他们拥有的表。他们必须将您的表与他们的表 JOIN，可以是直接，也可以是传递（也就是说，将他们的表联接到另一个表，而另一个表又联接到您的表）。  | 

以下是传递联接的示例。

```
ON 
my_table.identifer = third_party_table.identifier
....
ON
third_party_table.identifier = member_who_can_query_table.id
```

**注意**  
可以查询的成员也可以使用 `joinRequired` 参数。在这种情况下，查询必须将其表与至少一个其他表联接。

### 维度控制
<a name="dimension-controls"></a>

*维度控制*控制可以对聚合列进行筛选、分组或聚合的列。


| 控件 | 定义 | 用法 | 
| --- | --- | --- | 
| dimensionColumns |  您允许可以查询的成员在 SELECT、WHERE、GROUP、BY 和 ORDER BY 中使用的列（如果有）。  |  `dimensionColumn` 可以在 SELECT (`select_grouping_column_expression`)、WHERE、GROUP BY 和 ORDER BY 中使用。 同一列不能同时是 a `dimensionColumn`、a `joinColumn`、 and/or a `aggregateColumn`。  | 

### 标量函数
<a name="scalar-functions"></a>

*标量函数*控制哪些标量函数可以在维度列上使用。


| 控件 | 定义 | 用法 | 
| --- | --- | --- | 
| scalarFunctions |  可在查询的 `dimensionColumns` 上使用的标量函数。  |  指定允许在 `dimensionColumns` 上应用的标量函数（如果有）（例如 CAST）。 标量函数不能在其他函数之上使用，也不能在其他函数中使用。标量函数的参数可以是列、字符串文本或数字文本。  | 

支持以下标量函数：
+ 数学函数 - ABS、CEILING、FLOOR、LOG、LN、ROUND、SQRT
+ 数据类型格式设置函数 — CAST, CONVERT, TO\$1CHAR, TO\$1DATE, TO\$1NUMBER, TO\$1TIMESTAMP
+ 字符串函数 - LOWER、UPPER、RTRIM、SUBSTRING
  + 对于 RTRIM，不允许使用自定义字符集进行修剪。
+ 条件表达式 — COALESCE
+ 日期函数 - EXTRACT、GETDATE、CURRENT\$1DATE、DATEADD
+ 其他函数 — TRUNC

有关详细信息，请参阅 [AWS Clean Rooms SQL 参考](https://docs.aws.amazon.com/clean-rooms/latest/sql-reference/sql-reference.html)。

## 聚合分析规则 — 查询结果控制
<a name="agg-query-results-controls"></a>

使用聚合查询结果控制，可以通过指定每个输出行必须满足的一个或多个条件来控制返回哪些结果。 AWS Clean Rooms 支持 `COUNT (DISTINCT column) >= X` 形式的聚合约束。此形式要求每行至少聚合从配置表中选择的 X 个不同值（例如，不同 `user_id` 值的最少个数）。即使提交的查询本身不使用指定的列，也会自动强制执行此最低阈值。它们是在来自协作中每个成员的已配置表的查询中的每个已配置表中共同强制执行的。

每个配置表的分析规则中必须有至少一个聚合约束。配置表所有者可以添加多个 `columnName` 和关联的 `minimum`，这些表将共同强制执行。

### 聚合约束
<a name="agg-constraints"></a>

*聚合约束* 控制返回查询结果中的哪些行。要返回，行必须满足聚合约束中指定的每列中指定的最小不同值数。即使在查询或分析规则的其他部分中未明确提及该列，此要求也适用。


| 控件 | 定义 | 用法 | 
| --- | --- | --- | 
| columnName |  在每个输出行必须满足的条件中使用的 `aggregateColumn`。  |  可以是已配置表中的任何列。  | 
| minimum |  要在查询结果中返回输出行（例如 COUNT DISTINCT），关联 `aggregateColumn` 必须具有的最小不同值个数。  |  `minimum` 的值必须至少为 2。  | 

## 聚合分析规则结构
<a name="agg-analysis-rule-template"></a>

以下示例显示了聚合分析规则的预定义结构。

在以下示例中，*`MyTable`* 指您的数据表。你可以用自己的信息替换每个*user input placeholder*信息。

```
{
  "aggregateColumns": [
    {
      "columnNames": [MyTable column names], "function": [Allowed Agg Functions]
    },
  ],
  "joinRequired": ["QUERY_RUNNER"],  
  "joinColumns": [MyTable column names],
  "dimensionColumns": [MyTable column names],
  "scalarFunctions": [Allowed Scalar functions],
  "outputConstraints": [
    {
      "columnName": [MyTable column names], "minimum": [Numeric value] 
    },
  ]
}
```

## 聚合分析规则 — 示例
<a name="agg-analysis-rule-example"></a>

以下示例演示了两家公司如何合作 AWS Clean Rooms 使用聚合分析。

A 公司有客户和销售数据。A 公司有兴趣了解产品退货活动。B 公司是 A 公司的零售商之一，有退货数据。B 公司也有对 A 公司有用的客户细分属性（例如，购买过相关产品、使用过零售商的客户服务）。B 公司不想提供行级客户退货数据和属性信息。B 公司只想为 A 公司启用一组查询，以最小聚合阈值获取重叠客户的聚合统计数据。

A 公司和 B 公司决定协作，以便 A 公司能够了解产品退货活动，并在 B 公司和其他渠道提供更好的产品。

为了创建协作并进行聚合分析，两家公司执行以下操作：

1. A 公司创建协作并创建成员身份。协作中的另一个成员是 B 公司。A 公司在协作中启用查询日志记录，并在其账户中启用查询日志记录。

1. B 公司在协作中创建成员身份。它在其账户中启用查询日志记录。

1. A 公司创建销售配置表。

1. A 公司将以下聚合分析规则添加到销售配置表中。

   ```
   {
     "aggregateColumns": [
       {
         "columnNames": [
           "identifier"
         ],
         "function": "COUNT_DISTINCT"
       },
       {
         "columnNames": [
           "purchases"
         ],
         "function": "AVG"
       },
       {
         "columnNames": [
           "purchases"
         ],
         "function": "SUM"
       }
     ],
     "joinColumns": [
       "hashedemail"
     ],
     "dimensionColumns": [
       "demoseg",
       "purchasedate",
       "productline"
     ],
     "scalarFunctions": [
       "CAST",
       "COALESCE",
       "TRUNC"
     ],
     "outputConstraints": [
       {
         "columnName": "hashedemail",
         "minimum": 2,
         "type": "COUNT_DISTINCT"
       },
     ]
   }
   ```

   `aggregateColumns` — A 公司想要计算销售数据和退货数据之间重叠的唯一客户数量。A 公司还想汇总 `purchases` 数量，以便与 `returns` 数量进行比较。

   `joinColumns` — A 公司想要使用 `identifier` 来匹配销售数据中的客户和退货数据中的客户。这将有助于 A 公司将退货与正确的采购相匹配。它还可以帮助 A 公司细分重叠的客户。

   `dimensionColumns` — A 公司使用 `dimensionColumns` 来筛选特定产品，比较一段时期内的购买和退货情况，确保退货日期在产品日期之后，并帮助细分重叠客户。

   `scalarFunctions` — A 公司选择 `CAST` 标量函数，以便在需要时根据 A 公司关联到协作的配置表更新数据类型格式。它还添加了标量函数，以便在需要时帮助格式化列。

   `outputConstraints` — A 公司设定了最低输出约束。它不需要限制结果，因为允许分析师从销售表中查看行级数据 
**注意**  
A 公司没有在分析规则中加入 `joinRequired`。它为他们的分析师提供了单独查询销售表的灵活性。

1. B 公司创建退货配置表。

1. B 公司将以下聚合分析规则添加到退货配置表中。

   ```
   {
     "aggregateColumns": [
       {
         "columnNames": [
           "identifier"
         ],
         "function": "COUNT_DISTINCT"
       },
       {
         "columnNames": [
           "returns"
         ],
         "function": "AVG"
       },
       {
         "columnNames": [
           "returns"
         ],
         "function": "SUM"
       }
     ],
     "joinColumns": [
       "hashedemail"
     ],
     "joinRequired": [
       "QUERY_RUNNER"
     ],
     "dimensionColumns": [
       "state",
       "popularpurchases",
       "customerserviceuser",
       "productline",
       "returndate"
     ],
     "scalarFunctions": [
       "CAST",
       "LOWER",
       "UPPER",
       "TRUNC"
     ],
     "outputConstraints": [
       {
         "columnName": "hashedemail",
         "minimum": 100,
         "type": "COUNT_DISTINCT"
       },
       {
         "columnName": "producttype",
         "minimum": 2,
         "type": "COUNT_DISTINCT"
       }
     ]
   }
   ```

   `aggregateColumns` — B 公司让 A 公司汇总 `returns` 以与购买数量进行比较。它们至少有一个聚合列，因为它们启用了聚合查询。

   `joinColumns` — B 公司让 A 公司在 `identifier` 上进行联接，以将退货数据中的客户与销售数据中的客户进行匹配。`identifier` 数据特别敏感，将其作为 `joinColumn` 可确保数据永远不会在查询中输出。

   `joinRequired` — B 公司要求对退货数据的查询必须与销售数据重叠。他们不想让 A 公司查询其数据集中的所有个人。他们还在协作协议中商定了这一限制。

   `dimensionColumns` — B 公司让 A 公司按 `state`、`popularpurchases` 和 `customerserviceuser` 进行筛选和分组，这些独特的属性有助于 A 公司进行分析。B 公司让 A 公司使用 `returndate` 筛选在 `purchasedate` 之后发生的 `returndate` 的输出。通过这种筛选，输出可以更准确地评估产品变更的影响。

   `scalarFunctions` — B 公司启用以下函数：
   + TRUNNC（表示日期）
   + LOWER 和 UPPER（如果 `producttype` 在数据中以不同的格式输入）
   + CAST（如果 A 公司需要将销售表中的数据类型转换为与退货中表的数据类型相同）

   A 公司不启用其他标量函数，因为他们认为查询不需要这些函数。

   `outputConstraints` — B 公司对 `hashedemail` 设定了最低输出约束，以帮助降低重新识别客户身份的能力。它还对 `producttype` 增加了最低输出约束，以降低重新识别退回的特定产品的能力。根据输出的维度（例如 `state`），某些产品类型可能更占优势。无论 A 公司在其数据中添加了什么输出约束，他们的输出约束都将始终得到执行。

1. A 公司创建了与协作的销售表关联。

1. B 公司创建了与协作的退货表关联。

1. A 公司运行查询（如以下示例），以更好地了解 B 公司的退货数量与 2022 年各地采购总量的对比情况。

   ```
   SELECT
     companyB.state,
     SUM(companyB.returns),
     COUNT(DISTINCT companyA.hashedemail)
   FROM
     sales companyA
     INNER JOIN returns companyB ON companyA.identifier = companyB.identifier
   WHERE
     companyA.purchasedate BETWEEN '2022-01-01' AND '2022-12-31' AND
     TRUNC(companyB.returndate) > companyA.purchasedate
   GROUP BY
     companyB.state;
   ```

1. A 公司和 B 公司查看查询日志。B 公司验证查询是否符合协作协议中上商定的内容。

## 聚合分析规则问题疑难解答
<a name="troubleshooting-agg-analysis-rule"></a>

使用此处的信息可帮助您诊断和修复在使用聚合分析规则时出现的常见问题。

**Topics**
+ [我的查询没有返回任何结果](#query-no-results)

### 我的查询没有返回任何结果
<a name="query-no-results"></a>

当没有匹配结果或匹配结果不符合一个或多个最低聚合阈值时，就会发生这种情况。

有关最低聚合阈值的更多信息，请参阅[聚合分析规则 — 示例](#agg-analysis-rule-example)。

# 列表分析规则
<a name="analysis-rules-list"></a>

在中 AWS Clean Rooms，*列表分析规则*输出行级列表，列出其添加到的已配置表与可以查询的成员的配置表之间的重叠部分。可以查询的成员运行包含列表分析规则的查询。

列表分析规则类型支持扩充和受众构建等使用案例。

有关此分析规则的预定义查询结构和语法的更多信息，请参阅[列表分析规则预定义结构](#intersection-list-params-template)。

列表分析规则的参数（在[列表分析规则 — 查询控制](#parameters-list-query-controls)中定义）具有查询控制。它的查询控制包括选择可以在输出中列出的列的功能。查询要求至少有一次与可以查询成员的配置表联接，可以是直接联接，也可以是传递联接。

不存在像[聚合分析规则](analysis-rules-aggregation.md)那样的查询结果控制。

列表查询只能使用数学运算符。它们不能使用其他函数（例如聚合或标量）。

**Topics**
+ [列表查询结构和语法](#list-query-controls)
+ [列表分析规则 — 查询控制](#parameters-list-query-controls)
+ [列表分析规则预定义结构](#intersection-list-params-template)
+ [列表分析规则 — 示例](#list-example)

## 列表查询结构和语法
<a name="list-query-controls"></a>

对具有列表分析规则的表的查询必须遵循以下语法。

```
--select_list_expression
SELECT DISTINCT column_name [[AS] column_alias ] [, ...] 

--table_expression
FROM table_name [[AS] table_alias ]
  [[INNER] JOIN table_name [[AS] table_alias] ON join_condition] [...]

--where_expression
[WHERE where_condition]          

--limit_expression
[LIMIT number]
```

下表解释前面语法中列出的每个表达式。


| Expression | 定义 | 示例 | 
| --- | --- | --- | 
| select\$1list\$1expression |  包含至少一个表列名的逗号分隔列表。 `DISTINCT` 参数是必需的。  `select_list_expression` 可以带或不带 `AS` 参数对列设置别名。 有关更多信息，请参阅 [AWS Clean Rooms SQL 参考](https://docs.aws.amazon.com/clean-rooms/latest/sql-reference/sql-reference.html)。   |  `SELECT DISTINCT segment`  | 
| table\$1expression |  使用 `join_condition` 连接到 `join_condition` 的表或表的联接。 `join_condition` 返回布尔值。 `table_expression` 支持： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules-list.html)  |  <pre>FROM consumer_table <br />INNER JOIN provider_table<br />ON<br />consumer_table.identifier1 = provider_table.identifier1<br />AND<br />consumer_table.identifier2 = provider_table.identifier2</pre>  | 
| where\$1expression | 返回布尔值的条件表达式。它可能包括以下内容：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/analysis-rules-list.html)支持的比较条件是 (`=, >, <, <=, >=, <>, !=, NOT, IN, NOT IN, LIKE, IS NULL, IS NOT NULL`)。支持的逻辑运算符是 (`AND, OR`)。`where_expression` 是可选项。 |  `WHERE state + '_' + city = 'NY_NYC'` `WHERE timestampColumn = timestampColumn2 - 14`   | 
| limit\$1expression |  此表达式必须采用正整数。 `limit_expression` 是可选项。  |  `LIMIT 100`  | 

关于列表查询的结构和语法，请注意以下几点：
+ 不支持除 SELECT 之外的 SQL 命令。
+ 不支持子查询和通用表格表达式（例如 WITH）。
+ 不支持 HAVING、GROUP BY 和 ORDER BY 子句
+ 不支持 OFFSET 参数

## 列表分析规则 — 查询控制
<a name="parameters-list-query-controls"></a>

使用列表查询控制，您可以控制如何使用表中的列来查询表。例如，您可以控制哪一列用于联接，或者 SELECT 语句和 WHERE 子句中可以使用哪一列。

下面几节解释每种控制。

**Topics**
+ [联接控制](#list-controls-join-controls)
+ [列表控制](#list-controls)

### 联接控制
<a name="list-controls-join-controls"></a>

使用*联接控制*，您可以控制如何将您的表连接到 **table\$1expression** 中的其他表。 AWS Clean Rooms 仅支持 INNER JOIN。在列表分析规则中，至少需要一个 INNER JOIN，并且可以查询的成员必须在 INNER JOIN 中包含自己拥有的表。这意味着他们必须直接或通过传递方式将您的表与他们的表联接起来。

以下是传递联接的示例。

```
ON 
my_table.identifer = third_party_table.identifier 
.... 
ON 
third_party_table.identifier = member_who_can_query_table.id
```

INNER JOIN 语句只能使用在分析规则中明确归类为 `joinColumn` 的列。

INNER JOIN 必须对您的已配置表中的 `joinColumn` 和协作中另一个已配置表中的 `joinColumn` 进行操作。您可以决定表中的哪些列可以用作 `joinColumn`。

ON 子句中的每个匹配条件都要求在两列之间使用相等比较条件 (`=`)。

ON 子句中的多个匹配条件可以是：
+ 使用 `AND` 逻辑运算符组合
+ 使用 `OR` 逻辑运算符分隔

**注意**  
所有 JOIN 匹配条件都必须与 JOIN 两侧各一条记录匹配。所有由 `OR` 或 `AND` 逻辑运算符连接的条件也必须遵守此要求。

以下是使用 `AND` 逻辑运算符的查询示例。

```
SELECT some_col, other_col 
FROM table1 
    JOIN table2 
    ON table1.id = table2.id AND table1.name = table2.name
```

以下是使用 `OR` 逻辑运算符的查询示例。

```
SELECT some_col, other_col 
FROM table1 
    JOIN table2 
    ON table1.id = table2.id OR table1.name = table2.name
```


| 控件 | 定义 | 用法 | 
| --- | --- | --- | 
| joinColumns | 您希望允许可以查询的成员在 INNER JOIN 语句中使用的列。 |  同一列不能同时归类为 `joinColumn` 和 `listColumn`（参阅[列表控制](#list-controls)）。 除了 INNER JOIN 之外，不能在查询的任何其他部分中使用 `joinColumn`。  | 

### 列表控制
<a name="list-controls"></a>

*列表控制*用于控制可在查询输出中列出（即在 SELECT 语句中使用）或用于筛选结果（即在 WHERE 语句中使用）的列。


| 控件 | 定义 | 用法 | 
| --- | --- | --- | 
| listColumns | 您允许可以查询的成员在 SELECT 和 WHERE 中使用的列。 | listColumn 可以在 SELECT 和 WHERE 中使用。同一列不能同时用作 `listColumn` 和 `joinColumn`。 | 

## 列表分析规则预定义结构
<a name="intersection-list-params-template"></a>

以下示例包括一个预定义的结构，该结构向您展示了如何完成列表分析规则。

在以下示例中，*`MyTable`* 指您的数据表。你可以用自己的信息替换每个*user input placeholder*信息。

```
{
  "joinColumns": [MyTable column name(s)],
  "listColumns": [MyTable column name(s)],
}
```

## 列表分析规则 — 示例
<a name="list-example"></a>

以下示例演示了两家公司如何合作 AWS Clean Rooms 使用列表分析。

A 公司有客户关系管理 (CRM) 数据。A 公司希望获得有关其客户的更多细分数据，以进一步了解他们的客户，并有可能使用属性作为其他分析的输入。B 公司的细分数据由他们根据第一方数据创建的独特细分属性组成。B 公司只想向 A 公司提供其数据与 A 公司数据重叠的客户的唯一细分属性。

两家公司决定进行协作，以便 A 公司能够扩充重叠的数据。A 公司是可以查询的成员，B 公司是贡献者。

为创建协作并在协作中运行列表分析，两家公司执行以下操作：

1. A 公司创建协作并创建成员身份。协作中的另一个成员是 B 公司。A 公司在协作中启用查询日志记录，并在其账户中启用查询日志记录。

1. B 公司在协作中创建成员身份。它在其账户中启用查询日志记录。

1. A 公司创建 CRM 配置表。

1. A 公司将分析规则添加到客户配置表中，如以下示例所示。

   ```
   {
     "joinColumns": [
       "identifier1",
       "identifier2"
     ],
     "listColumns": [
       "internalid",
       "segment1",
       "segment2",
       "customercategory"
     ]
   }
   ```

   `joinColumns`— A 公司希望使用 `hashedemail` and/or `thirdpartyid`（从身份供应商处获得）将 CRM 数据中的客户与来自细分市场的客户进行匹配。这将有助于确保 A 公司为合适的客户匹配扩充的数据。他们有两个 JoinColumns，可以提高分析的匹配率。

   `listColumns` — A 公司使用 `listColumns` 来获取他们在自己系统中使用的 `internalid` 旁边的扩充列。他们添加了 `segment1`、`segment2` 和 `customercategory`，以便通过在筛选器中使用它们，将扩充限制到特定的细分。

1. B 公司创建细分配置表。

1. B 公司将分析规则添加到细分配置表中。

   ```
   {
     "joinColumns": [
       "identifier2"
     ],
     "listColumns": [
       "segment3",
       "segment4"
     ]
   }
   ```

   `joinColumns`— B 公司让 A 公司在 `identifier2` 上进行联接，以便将细分数据中的客户与 CRM 数据相匹配。A 公司和 B 公司与身份供应商合作，以获得与此协作相匹配的 `identifier2`。他们之所以没有添加其他 `joinColumns`，是因为他们认为 `identifier2` 可以提供最高和最准确的匹配率，而且查询不需要其他标识符。

   `listColumns` — B 公司让 A 公司使用 `segment3` 和 `segment4` 属性来扩充其数据，这些属性是他们（与客户 A）一起创建、收集和调整的独特属性，是数据扩充的一部分。他们希望 A 公司在行级获取这些重叠的细分，因为这是一项数据扩充协作。

1. A 公司创建了与协作的 CRM 表关联。

1. B 公司创建了与协作的细分表关联。

1. A 公司运行查询（例如以下查询）以扩充重叠的客户数据。

   ```
   SELECT companyA.internalid, companyB.segment3, companyB.segment4
   INNER JOIN returns companyB
    ON companyA.identifier2 = companyB.identifier2
   WHERE companyA.customercategory > 'xxx'
   ```

1. A 公司和 B 公司查看查询日志。B 公司验证查询是否符合协作协议中上商定的内容。

# 中的自定义分析规则 AWS Clean Rooms
<a name="analysis-rules-custom"></a>

在中 AWS Clean Rooms，*自定义分析规则*是一种新型的分析规则，它允许在配置的表上运行自定义查询。自定义 SQL 查询仍然仅限于只有SELECT命令，但与[聚合](analysis-rules-aggregation.md#agg-query-controls)和[列表](analysis-rules-list.md#list-query-controls)查询相比，可以使用更多的 SQL 结构（例如，窗口函数、OUTER JOIN 或子查询；有关完整列表 CTEs，请参阅 [AWS Clean Rooms SQL 参考](https://docs.aws.amazon.com/clean-rooms/latest/sql-reference/sql-reference.html)）。自定义 SQL 查询不必遵循[聚合](analysis-rules-aggregation.md#agg-query-structure-syntax)和[列表](analysis-rules-list.md#list-query-controls)查询之类的查询结构。

与聚合和列表分析规则支持的使用案例相比，自定义分析规则支持更高级的使用案例，例如自定义归因分析、基准测试、增量分析和受众发现。这是对聚合和列表分析规则支持的使用案例的超集的补充。

自定义分析规则还支持差别隐私。差别隐私是一种在数学上非常严格的数据隐私保护框架。有关更多信息，请参阅 [AWS Clean Rooms 差异隐私](differential-privacy.md)。创建分析模板时， AWS Clean Rooms 差异隐私会检查该模板以确定其是否与 AWS Clean Rooms 差异隐私的通用查询结构兼容。此验证可确保您不会创建对于差别隐私保护表不允许的分析模板。

要配置自定义分析规则，数据所有者可以选择允许存储在[分析模板](create-analysis-template.md)中的特定自定义查询在其配置表上运行。数据所有者在将分析模板添加到自定义分析规则中允许的分析控制之前应先审核这些模板。分析模板仅在创建这些模板的协作中可用和可见（即使该表与其他协作关联），并且只能由可以在该协作中进行查询的成员运行。

或者，成员可以选择允许其他成员（查询提供者）无需审核即可创建查询。成员在自定义分析规则添加允许的查询提供者控制的查询提供者账户。如果查询提供者是可以查询的成员，则他们可以直接在配置表上运行任何查询。查询提供者还可以通过创建[分析模板](create-analysis-template.md)来创建查询。在存在查询提供程序和关联表的所有协作中，自动允许查询提供者创建的任何查询在表上运行。 AWS 账户 

数据所有者只能允许分析模板或账户创建查询，不能同时允许两者创建。如果数据所有者将其留空，则可以查询的成员将无法对配置表运行查询。

**Topics**
+ [自定义分析规则预定义结构](#custom-predefined-structure)
+ [自定义分析规则示例](#custom-example)
+ [具有差别隐私的自定义分析规则](#custom-diff-privacy)

## 自定义分析规则预定义结构
<a name="custom-predefined-structure"></a>

以下示例包含一个预定义的结构，说明了如何完成开启差别隐私的自定义分析规则。`userIdentifier` 值是唯一地标识您的用户的列，例如 *user\$1id*。如果在协作中具有两个或更多开启了差别隐私的表， AWS Clean Rooms 要求您在两个分析规则中配置与用户标识符列相同的列，以在表之间保持一致的用户定义。

```
{
  "allowedAnalyses": ["ANY_QUERY"] | string[],
  "allowedAnalysisProviders": [],
  "differentialPrivacy": {
    "columns": [
      {
        "name": "userIdentifier"
      }
    ]
  }
}
```

您可以：
+ 将分析模板 ARNs 添加到允许的分析控件。在这种情况下，不包括 `allowedAnalysisProviders` 控制。

  ```
  {
    allowedAnalyses: string[]
  }
  ```
+  AWS 账户 IDs 向`allowedAnalysisProviders`控件添加成员。在这种情况下，您可以将 `ANY_QUERY` 添加到 `allowedAnalyses` 控制。

  ```
  {
    allowedAnalyses: ["ANY_QUERY"],
    allowedAnalysisProviders: string[]
  }
  ```

## 自定义分析规则示例
<a name="custom-example"></a>

以下示例演示了两家公司如何合作 AWS Clean Rooms 使用自定义分析规则。

A 公司有客户和销售数据。A 公司有兴趣了解 B 公司网站上广告活动的销售增量。B 公司拥有对 A 公司有用的观众数据和细分属性（例如，他们观看广告时使用的设备）。

A 公司想在协作中运行一个特定的增量查询。

为创建协作并在协作中运行自定义分析，两家公司执行以下操作：

1. A 公司创建协作并创建成员身份。协作中的另一个成员是 B 公司。A 公司在协作中启用查询日志记录，并在其账户中启用查询日志记录。

1. B 公司在协作中创建成员身份。它在其账户中启用查询日志记录。

1. A 公司创建 CRM 配置表。

1. A 公司向销售配置表添加空的自定义分析规则。

1. A 公司将销售配置表与协作关联起来。

1. B 公司创建观众配置表。

1. B 公司在观众配置表中添加一个空的自定义分析规则。

1. B 公司将观众配置表与协作关联起来。

1. A 公司查看与协作关联的销售表和观众表，并创建分析模板，为活动月份添加增量查询和参数。

   ```
   {
       "analysisParameters": [
       {
           "defaultValue": ""
           "type": "DATE"
           "name": "campaign_month"
       }
       ],
       "description": "Monthly incrementality query using sales and viewership data"
       "format": "SQL"
       "name": "Incrementality analysis"
       "source": 
           "WITH labeleddata AS
           (
           SELECT hashedemail, deviceid, purchases, unitprice, purchasedate,
           CASE
               WHEN testvalue IN ('value1', 'value2', 'value3') THEN 0
               ELSE 1
           END AS testgroup
           FROM viewershipdata
           )
           SELECT labeleddata.purchases, provider.impressions
           FROM labeleddata 
           INNER JOIN salesdata
             ON labeleddata.hashedemail = provider.hashedemail
           WHERE MONTH(labeleddata.purchasedate) > :campaignmonth
           AND testgroup = :group
          "
   }
   ```

1. A 公司将其账户（例如 444455556666）添加到自定义分析规则允许的分析提供者控制中。他们之所以使用允许的分析提供者控制，是因为他们希望允许在销售配置表上运行他们创建的任何查询。

   ```
   {
     "allowedAnalyses": [
       "ANY_QUERY"
     ],
     "allowedAnalysisProviders": [
       "444455556666"
     ]
   }
   ```

1. B 公司在协作中看到创建的分析模板并查看其内容，包括查询字符串和参数。

1. B 公司确定分析模板实现了增量使用案例，并满足如何查询其观众配置表的隐私要求。

1. B 公司将分析模板 ARN 添加到观众表的自定义分析规则允许的分析控制中。他们之所以使用允许的分析控制，是因为他们只想允许在观众配置表上运行增量查询。

   ```
   {
     "allowedAnalyses": [
       "arn:aws:cleanrooms:us-east-1:111122223333:membership/41327cc4-bbf0-43f1-b70c-a160dddceb08/analysistemplate/1ff1bf9d-781c-418d-a6ac-2b80c09d6292"
     ]
   }
   ```

1. A 公司运行分析模板并使用参数值 `05-01-2023`。

## 具有差别隐私的自定义分析规则
<a name="custom-diff-privacy"></a>

在中 AWS Clean Rooms，自定义分析规则支持差异隐私。差别隐私是一种在数学上非常严格的数据隐私保护框架，可以帮助保护您的数据以防范重新识别尝试。

差异隐私支持综合分析，例如广告活动规划、 post-ad-campaign衡量、金融机构联盟中的基准测试以及医疗保健研究的 A/B 测试。

支持的查询结构和语法在 [查询结构和语法](#dp-query-structure-syntax) 中定义。

### 具有差别隐私的自定义分析规则示例
<a name="custom-diff-privacy-example"></a>

**注意**  
AWS Clean Rooms 差异隐私仅适用于数据存储在 Amazon S3 中的协作。

考虑上一节中介绍的[自定义分析规则示例](#custom-example)。该示例说明了如何使用差别隐私保护您的数据以防范重新识别尝试，同时允许您的合作伙伴从您的数据中了解业务关键型见解。假设 B 公司具有观众数据，并希望使用差别隐私保护其数据。为了完成差别隐私设置，B 公司完成以下步骤：

1. B 公司开启差别隐私，同时在观众配置表中添加自定义分析规则。B 公司选择 `viewershipdata.hashedemail` 以作为用户标识符列。

1. B 公司在协作中[添加差别隐私策略](configure-differential-privacy.md)，以使其观众数据表可供查询。B 公司选择默认策略以快速完成设置。

A 公司希望了解 B 公司网站上的广告活动的销售增量，并运行分析模板。由于该查询与 Diferation Privacy 的 AWS Clean Rooms 通用[查询结构](#dp-query-structure-syntax)兼容，因此查询可以成功运行。

### 查询结构和语法
<a name="dp-query-structure-syntax"></a>

包含至少一个开启了差别隐私的表的查询必须遵循以下语法。

```
query_statement:
    [cte, ...] final_select

 cte:
    WITH sub_query AS (
       inner_select
       [ UNION | INTERSECT | UNION_ALL | EXCEPT/MINUS ]
       [ inner_select ]
    )
   
 inner_select:
     SELECT [user_id_column, ] expression [, ...] 
     FROM table_reference [, ...] 
     [ WHERE condition ]
     [ GROUP BY user_id_column[, expression] [, ...] ] 
     [ HAVING condition ] 

 final_select:
     SELECT [expression, ...] | COUNT | COUNT_DISTINCT | SUM | AVG | STDDEV
     FROM table_reference [, ...]
     [ WHERE condition ]
     [ GROUP BY expression [, ...] ] 
     [ HAVING COUNT | COUNT_DISTINCT | SUM | AVG | STDDEV | condition ]
     [ ORDER BY column_list ASC | DESC ] 
     [ OFFSET literal ]
     [ LIMIT literal ]

 expression:
    column_name [, ...] | expression AS alias | aggregation_functions | window_functions_on_user_id | scalar_function | CASE | column_name math_expression [, expression]  
    
 window_functions_on_user_id:
    function () OVER (PARTITION BY user_id_column, [column_name] [ORDER BY column_list ASC|DESC])
```

**注意**  
对于差别隐私查询结构和语法，请注意以下事项：  
不支持子查询。
如果表或 CTE 涉及受差异隐私保护的数据，则公用表表达式 (CTEs) 应发出用户标识符列。应在用户级别完成筛选、分组和聚合。
final\$1select 允许使用 COUNT DISTINCT、COUNT、SUM、AVG 和 STDDEV 聚合函数。

有关差别隐私支持哪些 SQL 关键字的更多详细信息，请参阅 [AWS Clean Rooms 差异隐私的 SQL 功能](dp-sql-capabilities.md)。

# ID 映射表分析规则
<a name="analysis-rules-id-mapping-table"></a>

在中 AWS Clean Rooms，*ID 映射表分析规则*不是独立的分析规则。这种类型的分析规则由管理 AWS Clean Rooms 并用于连接不同的身份数据以方便查询。它会自动添加到 ID 映射表中，并且无法编辑。它会继承协作中其他分析规则的行为，前提是这些分析规则是同构分析规则。

ID 映射表分析规则对 ID 映射表强制执行安全措施。它限制协作成员使用 ID 映射表直接选择或检查两个成员数据集之间的非重叠人群。当在查询中与其他分析规则一起隐式使用时，ID 映射表分析规则用于保护 ID 映射表中的敏感数据。

使用 ID 映射表分析规则，在展开的 SQL 中 AWS Clean Rooms 强制执行 ID 映射表两侧的重叠。这样做可让您执行以下任务：
+ 在 JOIN 语句中使用 ID 映射表的重叠部分。

  AWS Clean Rooms 允许在 ID 映射表上使用INNERLEFT、或RIGHT联接，前提是它尊重重叠之处。为了保护敏感的映射信息，ID 映射表必须始终位于任何JOIN操作的 inner “” 端。例如，以下JOIN操作是有效的：
  + table LEFT JOIN id\$1mapping\$1table
  + id\$1mapping\$1table RIGHT JOIN table
  + table INNER JOIN id\$1mapping\$1table

  以下JOIN操作无效：
  + id\$1mapping\$1table LEFT JOIN table
  + table RIGHT JOIN id\$1mapping\$1table

  这样可以防止数据集中没有相应匹配项的映射记录被泄露。允许此类操作可能会泄露有关其他协作成员数据映射的敏感信息。
+ 在 JOIN 语句中使用映射表列。

  不能在以下语句中使用映射表列：SELECT、WHERE、HAVING、GROUP BY、或 ORDER BY（除非修改了源 ID 命名空间关联或目标 ID 命名空间关联的保护）。
+ 在扩展的 SQL 中， AWS Clean Rooms 还支持OUTERJOINJOIN、隐式和 CROSS JOIN。这些联接无法满足重叠要求。而是 AWS Clean Rooms 使用`requireOverlap`来指定必须连接哪些列。

支持的查询结构和语法在 [ID 映射表查询结构和语法](#id-mapping-table-query-controls) 中定义。

[ID 映射表分析规则查询控制](#parameters-id-mapping-query-controls) 中定义的分析规则的参数包括查询控制和查询结果控制。其查询控制包括要求在 JOIN 语句中使用 ID 映射表重叠部分的功能（即 `requireOverlap`）。

**Topics**
+ [ID 映射表查询结构和语法](#id-mapping-table-query-controls)
+ [ID 映射表分析规则查询控制](#parameters-id-mapping-query-controls)
+ [ID 映射表的分析规则预定义结构](#id-mapping-table-predefined-structure)
+ [ID 映射表分析规则 - 示例](#id-mapping-table-example)

## ID 映射表查询结构和语法
<a name="id-mapping-table-query-controls"></a>

对具有 ID 映射表分析规则的表的查询必须遵循以下语法。

```
--select_list_expression
SELECT 
provider.data_col, consumer.data_col 

--table_expression
FROM provider

JOIN idMappingTable idmt ON provider.id = idmt.sourceId

JOIN consumer ON consumer.id = idmt.targetId
```

### 协作表
<a name="collab-table-structure"></a>

下表表示 AWS Clean Rooms 协作中存在的已配置表。**cr\$1drivers\$1license** 和 **cr\$1insurance** 表中的 **id** 列都表示与 ID 映射表匹配的列。

**cr\$1drivers\$1license**


|  |  |  | 
| --- |--- |--- |
| id | 司机姓名 | 注册状态 | 
| 1 | 爱德华 | TX | 
| 2 | 达纳 | MA | 
| 3 | Gweneth | IL | 

**cr\$1insurance**


|  |  |  | 
| --- |--- |--- |
| id | 保单持有人\$1电子邮件 | 保单编号 | 
| a | eduardo@internal.company.com | 17f9d04e-f5be-4426-bdc4-250ed59c6529 | 
| b | gwen@internal.company.com | 3f0092db-2316-48a8-8d44-09cf8f6e6c64 | 
| c | rosa@internal.company.com | d7692e84-3d3c-47b8-b46d-a0d5345f0601 | 

### ID 映射表
<a name="id-mapping-table-structure"></a>

下表显示了在 **cr\$1drivers\$1license** 和 **cr\$1insurance** 表上匹配的现有 ID 映射表。并非所有条目都 IDs 适用于两个协作表。


|  |  | 
| --- |--- |
| cr\$1drivers\$1license\$1id | cr\$1insurance\$1id | 
| 1 | a | 
| 2 | null | 
| 3 | b | 
| null | c | 

ID 映射表分析规则仅允许对一组重叠数据运行查询，重叠数据如下所示：


|  |  |  |  |  |  | 
| --- |--- |--- |--- |--- |--- |
| cr\$1drivers\$1license\$1id | cr\$1insurance\$1id | 司机姓名 | 注册状态 | 保单持有人\$1电子邮件 | 保单编号 | 
| 1 | a | 爱德华 | TX | eduardo@internal.company.com | 17f9d04e-f5be-4426-bdc4-250ed59c6529 | 
| 3 | b | Gweneth | IL | gwen@internal.company.com | 3f0092db-2316-48a8-8d44-09cf8f6e6c64 | 

### 示例查询
<a name="id-mapping-table-example-queries"></a>

以下示例显示了 ID 映射表联接的有效位置：

```
-- Single ID mapping table
SELECT
    [ select_items ]FROM
    cr_drivers_license cr_dl
    [ INNER | LEFT ] JOIN cr_identity_mapping_table idmt ON idmt.cr_drivers_license_id = cr_dl.id
    [ INNER | RIGHT ] JOIN cr_insurance cr_in            ON idmt.cr_insurance_id       = cr_in.id
;
-- Single ID mapping table (Subquery)
SELECT
    [ select_items ]FROM (
    SELECT
        [ select_items ]
    FROM
        cr_drivers_license cr_dl
        [ INNER | LEFT ] JOIN cr_identity_mapping_table idmt ON idmt.cr_drivers_license_id = cr_dl.id
        [ INNER | RIGHT ] JOIN cr_insurance cr_in            ON idmt.cr_insurance_id       = cr_in.id
)
;
-- Single ID mapping table (CTE)
WITH
    matched_ids AS (
        SELECT
            [ select_items ]
        FROM
            cr_drivers_license cr_dl
            [ INNER | LEFT ] JOIN cr_identity_mapping_table idmt ON idmt.cr_drivers_license_id = cr_dl.id
            [ INNER | RIGHT ] JOIN cr_insurance cr_in            ON idmt.cr_insurance_id       = cr_in.id
    )SELECT
    [ select_items ]FROM
    matched_ids
;
```

### 注意事项
<a name="id-mapping-table-considerations"></a>

关于 ID 映射表查询的结构和语法，请注意以下几点：
+ 您不能对其进行编辑。
+ 默认情况下，它会应用于 ID 映射表。
+ 它在协作内部使用源和目标 ID 命名空间关联。
+ 默认情况下，ID 映射表配置为向来自 ID 命名空间的列提供默认保护。您可以修改此配置，以便来自 ID 命名空间（`sourceID` 或 `targetID`）的列可以出现在查询中的任何位置。有关更多信息，请参阅 [ID 中的命名空间 AWS Clean Rooms](working-with-id-namespaces.md)。
+ ID 映射表分析规则将继承协作中其他分析规则的 SQL 限制。

## ID 映射表分析规则查询控制
<a name="parameters-id-mapping-query-controls"></a>

使用 ID 映射表查询 AWS Clean Rooms 控件，控制如何使用表中的列来查询表。例如，它可以控制哪些列用于联接，哪些列需要重叠。ID 映射表分析规则还包括允许在不需要 JOIN 的情况下投影 `sourceID` 和/或 `targetID` 的功能。

下表介绍了每种控制。


| 控件 | 定义 | 用法 | 
| --- | --- | --- | 
| joinColumns | 可以查询的成员能在 INNER JOIN 语句中使用的列。 | 除了 INNER JOIN 之外，不能在查询的任何其他部分中使用 joinColumns。有关更多信息，请参阅 [联接控制](analysis-rules-aggregation.md#join-controls)。 | 
| dimensionColumns  | 可以查询的成员能在 SELECT 和 GROUP BY 语句中使用的列（如果有）。 |  可以在 SELECT 和 GROUP BY 中使用的 `dimensionColumn`。 可以显示为 `joinKeys` 的 `dimensionColumn`。 如果使用方括号指定 `dimensionColumns`，则只能在 JOIN 子句中使用它。  | 
| queryContraints:RequireOverlap |  ID 映射表中必须联接以便可以运行查询的列。  |  必须使用这些列对 ID 映射表和协作表执行 JOIN。  | 

## ID 映射表的分析规则预定义结构
<a name="id-mapping-table-predefined-structure"></a>

ID 映射表分析规则的预定义结构对 `sourceID` 和 `targetID` 应用默认保护。这意味着在查询中必须使用应用了保护的列。

您可以通过以下方式配置 ID 映射表分析规则：
+ `sourceID` 和 `targetID` 均受到保护

  在此配置中，不能同时投影 `sourceID` 和 `targetID`。引用 ID 映射表时，必须在 JOIN 中使用 `sourceID` 和 `targetID`。
+ 仅保护 `targetID`

  在此配置中，不能投影 `targetID`。引用 ID 映射表时，必须在 JOIN 中使用 `targetID`。可以在查询中使用 `sourceID`。
+ 仅保护 `sourceID`

  在此配置中，不能投影 `sourceID`。引用 ID 映射表时，必须在 JOIN 中使用 `sourceID`。可以在查询中使用 `targetID`。
+ `sourceID` 或 `targetID` 均不受保护

  在此配置中，ID 映射表不受可在查询中使用的任何特定强制措施的约束。

以下示例显示了对 `sourceID` 和 `targetID` 应用默认保护的 ID 映射表分析规则的预定义结构。在此示例中，ID 映射表分析规则仅允许对 `sourceID` 列和 `targetID` 列执行 INNER JOIN。

```
{
  "joinColumns": [
    "source_id",
    "target_id"
  ],
  "queryConstraints": [
    {
      "requireOverlap": {
        "columns": [
          "source_id",
          "target_id"
        ]
      }
    }
  ],
  "dimensionColumns": [] // columns that can be used in SELECT and JOIN
}
```

以下示例显示了对 `targetID` 应用保护的 ID 映射表分析规则的预定义结构。在此示例中，ID 映射表分析规则仅允许对 `sourceID` 列执行 INNER JOIN。

```
{
  "joinColumns": [
    "source_id",
    "target_id"
  ],
  "queryConstraints": [
    {
      "requireOverlap": {
        "columns": [
          "target_id"
        ]
      }
    }
  ],
  "dimensionColumns": [
    "source_id"
  ]
}
```

以下示例显示了对 `sourceID` 应用保护的 ID 映射表分析规则的预定义结构。在此示例中，ID 映射表分析规则仅允许对 `targetID` 列执行 INNER JOIN。

```
{
  "joinColumns": [
    "source_id",
    "target_id"
  ],
  "queryConstraints": [
    {
      "requireOverlap": {
        "columns": [
          "source_id"
        ]
      }
    }
  ],
  "dimensionColumns": [
    "target_id"
  ]
}
```

以下示例显示了不对 `sourceID` 或 `targetID` 应用保护的 ID 映射表分析规则的预定义结构。在此示例中，ID 映射表分析规则支持对 `sourceID` 列和 `targetID` 列执行 INNER JOIN。

```
{
  "joinColumns": [
    "source_id",
    "target_id"
  ],
  "queryConstraints": [
    {
      "requireOverlap": {
        "columns": []
      }
    }
  ],
  "dimensionColumns": [
    "source_id",
    "target_id"
  ]
}
```

## ID 映射表分析规则 - 示例
<a name="id-mapping-table-example"></a>

例如，公司可以使用 ID 映射表分析规则来使用多方 LiveRamp 转码，而不是编写引用个人身份信息 (PII) 的长瀑布语句。以下示例演示如何协作 AWS Clean Rooms 使用 ID 映射表分析规则。

A 公司是拥有客户和销售数据的广告商，这些数据将用作源。A 公司还代表合作各方进行转码，并提供 LiveRamp 证书。

B 公司是拥有事件数据的发布者，这些数据将被用作目标。

**注意**  
A 公司或 B 公司均可提供 LiveRamp 转码凭证并执行转码。

为创建支持在协作中运行 ID 映射表分析的协作，两家公司执行以下操作：

1. A 公司创建协作并创建成员身份。添加公司 B ，该公司还在协作中创建成员身份。

1. 公司 A 要么关联现有 ID 命名空间来源，要么 AWS Entity Resolution 数据匹配服务 使用 AWS Clean Rooms 控制台创建新的 ID 命名空间源。

   公司 A 创建一个配置表，其中包含他们的销售数据，以及对应于 ID 映射表中的 `sourceId` 的列。

   ID 命名空间源提供要转码的数据。

1. B 公司要么关联现有 ID 命名空间目标，要么 AWS Entity Resolution 数据匹配服务 使用 AWS Clean Rooms 控制台创建一个新的 ID 命名空间目标。

   公司 B 创建一个配置表，其中包含他们的事件数据，以及对应于 ID 映射表中的 `targetId` 的列。

   ID 命名空间目标不提供要转码的数据，只提供有关 LiveRamp 配置的元数据。

1. 公司 A 发现与协作关联的两个 ID 命名空间，并创建且填充一个 ID 映射表。

1. 公司 A 通过联接 ID 映射表对这两个数据集运行查询。

   ```
   --- this would be valid for Custom or List
   SELECT provider.data_col, consumer.data_col
   FROM provider
     JOIN idMappingTable-123123123123-myMappingWFName idmt 
        ON provider.id = idmt.sourceId
     JOIN consumer 
        ON consumer.id = idmt.targetId
   ```

# AWS Clean Rooms 差异隐私
<a name="differential-privacy"></a>

AWS Clean Rooms 差异隐私通过一种以数学为依据的技术帮助您保护用户的隐私，该技术只需单击几下即可通过直观的控件实现。作为一项完全托管的功能，无需事先体验差异化隐私即可帮助您防止重新识别用户。 AWS Clean Rooms 在运行时自动向查询结果添加经过精心校准的噪音量，以帮助保护您的个人级别数据。

AWS Clean Rooms Difersition Privacy 支持广泛的分析查询，非常适合各种用例，在这些用例中，查询结果中的少量错误不会影响分析的实用性。通过使用该功能，您的合作伙伴可以生成有关广告活动、投资决策、临床研究等的业务关键型见解，合作伙伴无需进行任何额外的设置。

AWS Clean Rooms 差异隐私可防止恶意使用标量函数或数学运算符符号的溢出或无效强制转换错误。

有关 AWS Clean Rooms 差分隐私的更多信息，请参阅以下主题。

**Topics**
+ [差异隐私](#dp-overview)
+ [差分隐私是如何 AWS Clean Rooms 运作的](#dp-how-it-works)
+ [差别隐私策略](dp-settings.md)
+ [AWS Clean Rooms 差异隐私的 SQL 功能](dp-sql-capabilities.md)
+ [Differential Privacy 查询技巧和示例](dp-query-tips-examples.md)
+ [AWS Clean Rooms 差异隐私的局限性](dp-limitations.md)

## 差异隐私
<a name="dp-overview"></a>

差别隐私仅允许聚合的见解，并掩盖任何个人数据在这些见解中的贡献。差别隐私保护协作数据，以防止可以接收结果的成员了解特定个人的数据。如果没有差别隐私，可以接收结果的成员可能会尝试添加或删除有关个人的记录，并观察查询结果差异以推断个人用户数据。

在开启差别隐私后，将在查询结果中添加指定数量的噪声以掩盖各个用户的贡献。如果能够接收结果的成员在从其数据集中删除有关个人的记录后试图观察查询结果的差异，则查询结果的可变性有助于阻止识别该个人的数据。 AWS Clean Rooms Difersial Privacy 使用[SampCert](https://github.com/leanprover/SampCert)采样器，这是由开发的经过验证的正确采样器实现。 AWS

## 差分隐私是如何 AWS Clean Rooms 运作的
<a name="dp-how-it-works"></a>

在[完成以下工作流程时，开启差异隐私的工作流程 AWS Clean Rooms](what-is.md#how-it-works)需要执行以下额外步骤 AWS Clean Rooms：

1. 在添加[自定义分析规则](analysis-rules-custom.md)时，您可以开启差别隐私。

1. [您为协作配置差别隐私策略](configure-differential-privacy.md)，以使受差别隐私保护的数据表可供查询。

完成这些步骤后，可以查询的成员可以开始对受差异隐私保护的数据进行查询。 AWS Clean Rooms 返回符合差异隐私政策的结果。 AWS Clean Rooms Differation Privacy 会跟踪您可以运行的剩余查询的估计数量，类似于显示汽车当前燃油水平的汽车中的汽油表。可以查询的成员可以运行的查询数量受[差别隐私策略](dp-settings.md)中设置的**隐私预算**和**每个查询添加的噪声**参数的限制。

### 注意事项
<a name="dp-considerations"></a>

在中使用差分隐私时 AWS Clean Rooms，请考虑以下几点：
+ 可以接收结果的成员无法使用差别隐私。他们将为配置的表配置自定义分析规则，并关闭差别隐私。
+ 如果两个或更多数据提供者都开启了差别隐私，可以查询的成员无法联接来自这些数据提供者的表。

# 差别隐私策略
<a name="dp-settings"></a>

差别隐私策略控制允许可以查询的成员在协作中运行多少个聚合函数。**隐私预算**定义一种通用的有限资源，该资源应用于协作中的所有表。**每个查询添加的噪声**控制隐私预算的耗尽速率。

需要具有差别隐私策略，才能使受差别隐私保护的表可供查询。这是协作中的一次性步骤，其中包括两个输入：
+ **隐私预算** - 以 epsilon 量化，隐私预算控制隐私保护级别。这是一种通用的有限资源，应用于协作中受差别隐私保护的所有表，因为目标是保护可能在多个表中包含信息的用户的隐私。

  每次对表运行查询时，都会使用**隐私预算**。在隐私预算用完时，可以查询的协作成员无法运行额外的查询，直到增加或刷新隐私预算。通过设置较大的隐私预算，可以接收结果的成员可以减少他们对数据中的个人的不确定性。在咨询业务决策者后，选择一个兼顾您的协作要求和隐私需求的隐私预算。

  如果您计划定期将新数据引入到一个协作中，您可以选择**每月刷新隐私预算**，以在每个日历月自动创建新的隐私预算。如果选择该选项，在两次刷新之间重复查询时，可能会泄露任意数量的数据行相关信息。如果在隐私预算刷新之间重复查询相同的行，请避免选择该选项。
+ **每个查询添加的噪声**是根据您希望掩盖其贡献的用户数量测量的。该值控制隐私预算的耗尽速率。较大的噪声值降低隐私预算的耗尽速率，因此，允许对数据运行更多查询。不过，这会导致发布的数据见解不太准确。在设置该值时，请考虑协作见解所需的准确性。

您可以使用默认的差异隐私策略来快速完成设置或根据您的用例自定义差异隐私政策。 AWS Clean Rooms 差异隐私提供了用于配置策略的直观控件。 AWS Clean Rooms Difersition Privacy 允许您根据数据的所有查询中可能的聚合数量来预览该实用程序，并估算在数据协作中可以运行多少查询。

您可以使用交互式示例，以了解**隐私预算**和**每个查询添加的噪声**的不同值如何影响不同类型的 SQL 查询的结果。一般来说，您需要兼顾隐私需求以及要允许的查询数量和这些查询的准确性。较小的**隐私预算**或较大的**每个查询添加的噪声**可以更好地保护用户隐私，但为协作合作伙伴提供不太有意义的见解。

如果您增加**隐私预算**，同时将**每个查询添加的噪声**参数保持不变，则可以查询的成员可以在协作中对您的表运行更多的聚合。您可以在协作期间随时增加**隐私预算**。如果您减少**隐私预算**，同时将**每个查询添加的噪声**参数保持不变，则可以查询的成员可以运行更少的聚合。在可以查询的成员开始分析您的数据后，您无法减少**隐私预算**。

如果您增加**每个查询添加的噪声**，同时将**隐私预算**输入保持不变，则可以查询的成员可以在协作中对您的表运行更多的聚合。如果您减少**每个查询添加的噪声**，同时将**隐私预算**输入保持不变，则可以查询的成员可以运行更少的聚合。您可以在协作期间随时增加或减少**每个查询添加的噪声**。

差别隐私策略是通过隐私预算模板 API 操作管理的。

# AWS Clean Rooms 差异隐私的 SQL 功能
<a name="dp-sql-capabilities"></a>

AWS Clean Rooms 差异隐私使用通用查询结构来支持复杂的 SQL 查询。根据此结构对自定义分析模板进行验证，以确保它们可以在受差别隐私保护的表上运行。下表指示支持哪些函数。请参阅[查询结构和语法](analysis-rules-custom.md#dp-query-structure-syntax)了解更多信息。


| 类别 | Spark 分析引擎支持的 SQL 结构 | 常用表表达式 (CTEs) | 最终 SELECT 子句 | 
| --- |--- |--- |--- |
| 聚合函数 |    ANY\$1VALUE 函数   APPROXIMATE PERCENTILE\$1DISC 函数   AVG 函数   COUNT 和 COUNT DISTINCT 函数   MAX 函数   MEDIAN 函数   MIN 函数   PERCENTILE\$1CONT 函数   STDDEV\$1SAMP 和 STDDEV\$1POP 函数   SUM 和 SUM DISTINCT 函数   VAR\$1SAMP 和 VAR\$1POP 函数    | 支持这样的条件： CTEs 使用受差异隐私保护的表必须生成具有用户级记录的数据。您应该 CTEs 使用`SELECT userIdentifierColumn...'格式编写 SELECT 表达式。 | 支持的聚合：AVG、COUNT、COUNT DISTINCT、STDDEV 和 SUM。 | 
| CTEs | WITH 子句、WITH 子句子查询 | 支持这样的条件： CTEs 使用受差异隐私保护的表必须生成具有用户级记录的数据。您应该 CTEs 使用`SELECT userIdentifierColumn...'格式编写 SELECT 表达式。 | 不适用 | 
| 子查询 |    SELECT   HAVING   JOIN   JOIN 条件   FROM   WHERE    | 在这些结构中，你可以有任何不引用差异隐私关系的子查询。您只能在 FROM 和 JOIN 子句中使用任何引用差异隐私关系的子查询。 | 
| 联接条款 |    INNER JOIN   LEFT JOIN   左半连接   左边反连接   RIGHT JOIN   FULL JOIN   [JOIN] OR 运算符   CROSS JOIN    |  支持的条件是，仅支持对用户标识符列进行等值联接的 JOIN 函数；在查询两个或更多开启了差别隐私的表时，必须使用这些函数。确保必需的等值联接条件是正确的。确认表所有者在所有表中配置了相同的用户标识符列，以便用户的定义在表之间保持一致。 在合并两个或更多开启了差别隐私的关系时，不支持 CROSS JOIN 函数。  | 
| 集合运算符 | UNION、UNION ALL、INTERSECT、除外 \$1 减号（这些是同义词） | UNION、UNION ALL、INTERSECT、除外 \$1 减号（这些是同义词） | 不支持 | 
| 窗口函数 |  聚合函数   AVG 窗口函数   COUNT 窗口函数   CUME\$1DIST 开窗函数   DENSE\$1RANK 窗口函数   FIRST\$1VALUE 窗口函数   LAG 窗口函数   LAST\$1VALUE 窗口函数   LEAD 窗口函数   MAX 窗口函数   MEDIAN 窗口函数   MIN 窗口函数   NTH\$1VALUE 窗口函数   STDDEV\$1SAMP 和 STDDEV\$1POP 窗口函数（STDDEV\$1SAMP 和 STDDEV 是同义词）   SUM 窗口函数   VAR\$1SAMP 和 VAR\$1POP 窗口函数（VAR\$1SAMP 和 VARIANCE 是同义词）   排名函数   DENSE\$1RANK 窗口函数   NTILE 窗口函数   PERCENT\$1RANK 开窗函数   RANK 窗口函数   ROW\$1NUMBER 窗口函数    | 在查询开启差异隐私的关系时，窗口函数的分区子句中的用户标识符列是必填的，条件是所有这些都支持。 | 不支持 | 
| 条件表达式 |    CASE 条件表达式   COALESCE 表达式   GREATEST 和 LEAST 函数   NVL 和 COALESCE 函数   NVL2 函数   NULLIF 函数    | 全部支持 | 全部支持 | 
| Conditions |    比较条件   逻辑条件   模式匹配条件   BETWEEN 范围条件   Null 条件    | EXISTS并且IN无法使用，因为它们需要子查询。支持所有其他内容。 | 全部支持 | 
| 日期时间函数 |    事务中的日期和时间函数   串联运算符   ADD\$1MONTHS 函数   CONVERT\$1TIMEZONE 函数   CURRENT\$1DATE 函数   DATEADD 函数   DATEDIFF 函数   DATE\$1PART 函数   DATE\$1TRUNC 函数   EXTRACT 函数   TO\$1TIMESTAMP 函数   日期或时间戳函数的日期部分    | 全部支持 | 全部支持 | 
| 字符串函数 |    \$1\$1（串联）运算符   BTRIM 函数   CHAR\$1LENGTH 函数   CHARACTER\$1LENGTH 函数   CONCAT 函数   LEFT 和 RIGHT 函数   LEN 函数   LENGTH 函数   LOWER 函数   LPAD 和 RPAD 函数   LTRIM 函数   POSITION 函数   REGEXP\$1COUNT 函数   REGEXP\$1INSTR 函数   REGEXP\$1REPLACE 函数   REGEXP\$1SUBSTR 函数   REPEAT 函数   REPLACE 函数   REVERSE 函数   RTRIM 函数   SPLIT\$1PART 函数   SUBSTRING 函数   TRANSLATE 函数   TRIM 函数   UPPER 函数    | 全部支持 | 全部支持 | 
| 数据类型格式设置函数 |    CAST 函数   TO\$1CHAR   TO\$1DATE 函数   TO\$1NUMBER   日期时间格式字符串   数字格式字符串    | 全部支持 | 全部支持 | 
| 哈希函数 |    AES\$1加密   AES\$1DECRYPT   ENCODE   DECODE   MD5 函数   SHA1 函数   SHA2 函数   XX\$1 HASH64    | 全部支持 | 全部支持 | 
| 数学运算符符号 | \$1、-、\$1、/、% 和 @ | 全部支持 | 全部支持 | 
| 数学函数 |    ABS 函数   ACOS 函数   ASIN 函数   ATAN 函数   ATAN2 函数   CBRT 函数   CEILING（或 CEIL）函数   COS 函数   COT 函数   DEGREES 函数   LTRIM 函数   EXP 函数   FLOOR 函数   LN 函数   LOG 函数   MOD 函数   PI 函数   POWER 函数   RADIANS 函数   RANDOM 函数   ROUND 函数   SIGN 函数   SIN 函数   SQRT 函数   TRUNC 函数    | 全部支持 | 全部支持 | 
| VARBYTE 函数 |    UNHEX，   UNBASE64   十六进制    HLL\$1SKETCH\$1AGG，    HLL\$1SKETCH\$1ESTIMATE   HLL\$1UNION   HLL\$1UNION\$1AGG    | 全部支持 | 全部支持 | 
| JSON |    TO\$1JSON   GET\$1JSON\$1OBJECT    | 全部支持 | 全部支持 | 
| 数组函数 |    数组\$1包含   数组\$1不同   数组\$1除外   数组\$1相交   ARRAY\$1JOIN   数组\$1删除   数组\$1排序   ARRAY\$1UNION    | 不支持 | 不支持 | 
| 扩展分组依据 | 分组集、汇总、立方体 | 不支持 | 不支持 | 
| 排序操作 | ORDER BY | 支持 ORDER BY 子句，条件是只有在开启差分隐私的情况下查询表时，窗口函数的分区子句才支持 ORDER BY 子句。 | 支持 | 
| 行数限制 | LIMIT、OFFSET | 不支持 CTEs 使用受差异隐私保护的表 | 全部支持 | 
| 表和列别名 |   | 支持 | 支持 | 
| 聚合函数上的数学函数 |   | 支持 | 支持 | 
| 聚合函数中的标量函数 |   | 支持 | 支持 | 

## 不支持的 SQL 构造的常见替代方案
<a name="common-alternatives"></a>


| 类别 | SQL 构造 | 或者 | 
| --- |--- |--- |
|  窗口函数  |    LISTAGG   PERCENTILE\$1CONT   PERCENTILE\$1DISC    | 您可以将等效的聚合函数与 GROUP BY 一起使用。 | 
| 数学运算符符号 |    \$1column \$1\$1/ 2   \$1column \$1/ 2   \$1column ^ 2    |    CBRT   SQRT   POWER(\$1column, 2)    | 
| 标量函数 |    SYSDATE   \$1column::integer   convert(type, \$1column)    |    CURRENT\$1DATE   CAST \$1column AS integer   CAST \$1column AS type    | 
| 文本 | 间隔 '1 秒' | 间隔 '1' 秒 | 
| 行限制 | TOP n | 限制 n | 
| 联接 |    USING   NATURAL    | ON 子句应明确包含连接标准。 | 

# Differential Privacy 查询技巧和示例
<a name="dp-query-tips-examples"></a>

AWS Clean Rooms 差异隐私使用[通用查询结构](dp-sql-capabilities.md)来支持各种 SQL 结构，例如用于数据准备的公用表表达式 (CTEs) 和常用的聚合函数`COUNT`，例如、或。`SUM`为了通过在运行时向聚合查询结果添加噪音来混淆任何可能的用户在数据中的贡献，Difersient Privacy 要求最终`SELECT statement`版本中的聚合函数在用户级数据上运行。 AWS Clean Rooms 

以下示例使用来自一个媒体发布者的两个名为 `socialco_impressions` 和 `socialco_users` 的表，该发布者希望使用差别隐私保护数据，同时与一个具有 `athletic_brand_sales` 数据的运动品牌协作。该媒体发布者已将 `user_id` 列配置为用户标识符列，同时在 AWS Clean Rooms中启用差别隐私。广告商不需要差异隐私保护，而是希望使用组合数据 CTEs 进行查询。由于他们的 CTE 使用受差别隐私保护的表，因此，广告商将这些受保护的表中的用户标识符列包含在 CTE 列的列表中，并根据用户标识符列联接这些受保护的表。

```
WITH matches_table AS(
     SELECT si.user_id, si.campaign_id, s.sale_id, s.sale_price
     FROM socialco_impressions si
     JOIN socialco_users su
         ON su.user_id = si.user_id
     JOIN athletic_brand_sales s
         ON s.emailsha256 = su.emailsha256
     WHERE s.timestamp > si.timestamp
    
UNION ALL
 
     SELECT si.user_id, si.campaign_id, s.sale_id, s.sale_price
     FROM socialco_impressions si
     JOIN socialco_users su
         ON su.user_id = si.user_id
     JOIN athletic_brand_sales s
         ON s.phonesha256 = su.phonesha256
     WHERE s.timestamp > si.timestamp
)
        
SELECT COUNT (DISTINCT user_id) as unique_users
FROM matches_table
GROUP BY campaign_id
ORDER BY COUNT (DISTINCT user_id) DESC
LIMIT 5
```

同样，如果要对受差别隐私保护的数据表运行窗口函数，您必须在 `PARTITION BY` 子句中包含用户标识符列。

```
ROW_NUMBER() OVER (PARTITION BY conversion_id, user_id ORDER BY match_type, match_age) AS row
```

# AWS Clean Rooms 差异隐私的局限性
<a name="dp-limitations"></a>

AWS Clean Rooms 差异隐私不能解决以下情况：

1. AWS Clean Rooms 差异隐私仅支持使用 Amazon S3 支持的 AWS Glue 表进行查询。它不支持使用 Snowflake 或 Amazon Athena 表进行查询。

1. AWS Clean Rooms 差异隐私无法解决定时攻击。例如，如果单个用户贡献大量的行，并且添加或删除该用户显著改变查询计算时间，则可能会受到这些攻击。

1. AWS Clean Rooms 当 SQL 查询可能由于使用某些 SQL 结构而在运行时导致溢出或无效的强制转换错误时，差异隐私不能保证差异隐私。

   下表列出了一些（但不是全部）可能会产生运行时错误而应当在分析模板中进行验证的 SQL 构造。我们建议您批准能够最大限度地减少出现此类运行时错误次数的分析模板，并定期查看查询日志，确定查询是否符合协作协议。

   以下 SQL 构造容易出现溢出错误：    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/dp-limitations.html)

1. CAST 数据类型格式化函数容易出现无效的强制转换错误。

   您可以配置[CloudWatch 为为日志组创建指标筛选器](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CreateMetricFilterProcedure.html)，然后在该指标筛选器上[创建 CloudWatch 警](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Alarm-On-Logs.html)报，以便在遇到潜在的溢出或投射错误时接收警报。

   具体而言，您应该关注错误代码 `CastError`、`OverflowError`、`ConversionError`。存在这些错误代码表示可能存在侧信道攻击，但也可能表示存在错误的 SQL 查询。

   有关更多信息，请参阅 [分析登录 AWS Clean Rooms](query-logs.md)。

# AWS 无尘室机器学习
<a name="machine-learning"></a>

AWS Clean Rooms ML 允许两个或多个参与方在其数据上运行机器学习模型，而无需彼此共享数据。该服务提供增强隐私的控件，使数据所有者能够安全地保护自己的数据和模型 IP。您可以使用 AWS 创作模型或自带自定义模型。

有关其工作方式的更详细说明，请参阅[跨账户作业](ml-behaviors.md#ml-behaviors-cross-account-jobs)。

有关 Clean Rooms 机器学习模型功能的更多信息，请参阅以下主题。

**Topics**
+ [AWS Clean Rooms 机器学习术语](#ml-terminology)
+ [AWS Clean Rooms ML 如何与 AWS 模型配合使用](#ml-how-it-works)
+ [AWS Clean Rooms ML 如何使用自定义模型](#custML-how-it-works)
+ [AWS Clean Rooms ML 中的模型](aws-models.md)
+ [Clean Rooms ML 中的自定义模型](custom-models.md)

## AWS Clean Rooms 机器学习术语
<a name="ml-terminology"></a>

使用 Clean Rooms ML 时，了解以下术语非常重要：
+ *训练数据提供者* - 贡献训练数据、创建和配置相似模型并将该相似模型与一个协作关联的一方。
+ *种子数据提供者* - 贡献种子数据、生成相似细分并导出其相似细分的一方。
+ *训练数据* - 训练数据提供者的数据，用于生成相似模型。训练数据用于测量用户行为的相似性。

  训练数据必须包含用户 ID、项目 ID 和时间戳列。（可选）训练数据可以包含其他交互作为数值或分类特征。举例而言，交互可以是观看的视频、购买的物品或阅读的文章列表。
+ *种子数据* - 种子数据提供者的数据，用于创建相似细分。种子数据可以直接提供，也可以来自 AWS Clean Rooms 查询结果。相似细分输出是训练数据中与种子用户最相似的一组用户。
+ *相似模型* - 训练数据的机器学习模型，用于在其他数据集中查找相似用户。

  在使用 API 时，*受众模型* 术语等同于相似模型。例如，您可以使用 [CreateAudienceModel](https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_CreateAudienceModel.html)API 创建外观相似的模型。
+ *相似细分* - 是与种子数据最相似的训练数据子集。

  使用 API 时，您可以使用 API 创建外观相似的[StartAudienceGenerationJob](https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_StartAudienceGenerationJob.html)区段。

训练数据提供者的数据绝不会与种子数据提供者共享，并且种子数据提供者的数据绝不会与训练数据提供者共享。相似细分输出与训练数据提供者共享，但绝不会与种子数据提供者共享。

## AWS Clean Rooms ML 如何与 AWS 模型配合使用
<a name="ml-how-it-works"></a>

![\[概述 AWS Clean Rooms ML 如何与 AWS 模型配合使用。\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/images/howItWorksML.png)


使用相似模型需要两方，即训练数据提供者和种子数据提供者，按顺序合作，将他们的数据整合到协作中 AWS Clean Rooms 。以下是训练数据提供者必须先完成的工作流程：

1. 训练数据提供者的数据必须存储在用户-项目交互 AWS Glue 的数据目录表中。训练数据必须至少包含用户 ID 列、交互 ID 列和时间戳列。

1. 训练数据提供者向注册训练数据 AWS Clean Rooms。

1. 训练数据提供者创建一个相似模型，可以将其与多个种子数据提供者共享。相似模型是一种深度神经网络，训练时间可能长达 24 小时。它不会自动重新训练，我们建议您每周重新训练一次。

1. 训练数据提供者配置相似模型，包括是否共享相关性指标以及输出细分的 Amazon S3 位置。训练数据提供者可以通过单个相似模型创建多个配置的相似模型。

1. 训练数据提供者将配置的受众模型关联到与某个种子数据提供者共享的协作。

以下是种子数据提供者接下来必须完成的工作流程：

1. 种子数据提供者的数据可以存储在 Amazon S3 存储桶中，也可以来自查询结果。

1. 种子数据提供者开启与训练数据提供者共享的协作。

1. 种子数据提供者从协作页面的“Clean Rooms ML”选项卡中创建一个相似细分。

1. 种子数据提供者可以评估相关性指标（如果已共享），并导出相似细分以在 AWS Clean Rooms外部使用。

## AWS Clean Rooms ML 如何使用自定义模型
<a name="custML-how-it-works"></a>

借助 Clean Rooms ML，协作成员可以使用存储在 Amazon ECR 中的 dockerized 自定义模型算法来共同分析他们的数据。为此，*模型提供者*必须创建图像并将其存储在 Amazon ECR 中。按照 [Amazon Elastic Container Registry 用户指南](https://docs.aws.amazon.com/AmazonECR/latest/userguide/)中的步骤创建包含自定义 ML 模型的私有存储库。

协作中的任何成员都可以成为*模型提供者*，前提是他们拥有正确的权限。协作的所有成员都可以向模型贡献训练数据、推理数据或两者兼而有之。在本指南中，提供数据的成员被称为*数据提供者*。创建协作的成员是协作创建*者*，该成员可以是*模型提供者，也可以是*数据提供**者之一，或者两者兼而有之。

在最高级别，以下是执行自定义 ML 建模必须完成的步骤：

1. 协作创建者创建协作并为每个成员分配适当的成员能力和付款配置。协作创建者必须在此步骤中将成员接收模型输出或接收推理结果的能力分配给相应的成员，因为协作创建后无法对其进行更新。有关更多信息，请参阅 [在 AWS Clean Rooms ML 中创建和加入合作](create-custom-ml-collaboration.md)。

1. 模型提供者配置其容器化机器学习模型并将其与协作关联，并确保为导出的数据设置隐私约束。有关更多信息，请参阅 [在 AWS Clean Rooms ML 中配置模型算法](configure-model-algorithm.md)。

1. 数据提供者将其数据贡献给合作，并确保其隐私需求得到具体说明。数据提供者必须允许模型访问其数据。有关更多信息，请参阅[在 AWS Clean Rooms ML 中贡献训练数据](custom-model-training-data.md)和[在 AWS Clean Rooms ML 中关联配置的模型算法](associate-model-algorithm.md)。

1. 协作成员创建 ML 配置，该配置定义了模型工件或推理结果的导出位置。

1. 协作成员创建一个 ML 输入通道，为训练容器或推理容器提供输入。机器学习输入通道是一个查询，用于定义要在模型算法的上下文中使用的数据。

1. 协作成员使用 ML 输入通道和配置的模型算法调用模型训练。有关更多信息，请参阅 [在 AWS Clean Rooms ML 中创建经过训练的模型](create-trained-model.md)。

1. （可选）模型训练器调用模型导出作业，并将模型工件发送到模型结果接收器。只有具有有效 ML 配置且成员能够接收模型输出的成员才能接收模型工件。有关更多信息，请参阅 [从 AWS Clean Rooms ML 中导出模型工件](export-model-artifacts.md)。

1. （可选）协作成员使用 ML 输入通道、经过训练的模型 ARN 和推理配置的模型算法调用模型推理。推理结果将发送到推理输出接收器。只有具有有效 ML 配置且成员能够接收推理输出的成员才能接收推理结果。

以下是*模型提供者*必须完成的步骤：

1. 创建与 A SageMaker I 兼容的 Amazon ECR docker 镜像。Clean Rooms ML 仅支持与 SageMaker AI 兼容的 docker 镜像。

1. 创建与 SageMaker AI 兼容的 docker 镜像后，将该镜像推送到 Amazon ECR。按照 [Amazon 弹性容器注册表用户指南](https://docs.aws.amazon.com/AmazonECR/latest/userguide/)中的说明创建容器训练镜像。

1. 配置模型算法以在 Clean Rooms ML 中使用。

   1. 提供 Amazon ECR 存储库链接和配置模型算法所需的所有参数。

   1. 提供服务访问角色，允许 Clean Rooms ML 访问 Amazon ECR 存储库。

   1. 将配置的模型算法与协作关联。这包括提供隐私政策，该政策定义了对容器日志、故障日志、 CloudWatch 指标的控制以及对可以从容器结果中导出多少数据的限制。

以下是*数据提供者*为与自定义 ML 模型协作而必须完成的步骤：

1. 使用自定义分析规则配置现有 AWS Glue 表。这允许一组特定的预先批准的查询或预先批准的账户使用您的数据。

1. 将您配置的表与协作关联，并提供可以访问您的 AWS Glue 表格的服务访问角色。

1. 向表中@@ [添加协作分析规则](add-collaboration-analysis-rule.md)，允许配置的模型算法关联访问配置的表。

1. 在 Clean Rooms ML 中关联和配置模型和数据后，能够运行查询的成员提供 SQL 查询并选择要使用的模型算法。

 模型训练完成后，该成员启动模型训练工件或推理结果的导出。这些工件或结果将发送给能够接收经过训练的模型输出的成员。结果接收器必须`MachineLearningConfiguration`先对其进行配置，然后才能接收模型输出。

# AWS Clean Rooms ML 中的模型
<a name="aws-models"></a>

AWS Clean Rooms ML 为双方提供了一种隐私保护方法，便于双方识别其数据中的相似用户，而无需彼此共享数据。第一方将训练数据带到， AWS Clean Rooms 这样他们就可以创建和配置外观相似的模型并将其与协作关联起来。然后，会将种子数据引入到协作中，以便创建与训练数据类似的相似细分。

有关其工作方式的更详细说明，请参阅[跨账户作业](ml-behaviors.md#ml-behaviors-cross-account-jobs)。

以下主题提供有关如何在 Clean Rooms ML 中创建和配置 AWS 模型的信息。

**Topics**
+ [AWS Clean Rooms ML 的隐私保护](ml-privacy.md)
+ [Clean Rooms ML 的训练数据要求](ml-training-data-requirements.md)
+ [Clean Rooms ML 的种子数据要求](ml-seed-data-requirements.md)
+ [AWS Clean Rooms 机器学习模型评估指标](ml-metrics.md)

# AWS Clean Rooms ML 的隐私保护
<a name="ml-privacy"></a>

Clean Rooms ML 旨在降低*成员身份推断攻击*的风险；通过这种推断攻击，训练数据提供者可以了解哪些成员位于种子数据中，种子数据提供者可以了解哪些成员位于训练数据中。我们采取了一些措施以防范这种攻击。

首先，种子数据提供者不直接观察 Clean Rooms ML 输出，同时训练数据提供者也根本无法观察种子数据。种子数据提供者可以选择将种子数据包含在输出细分中。

接下来，通过训练数据的随机样本创建相似模型。该样本包含大量与种子受众不匹配的用户。此过程使得确定用户是否不在数据中变得更加困难，这是推断成员资格的另一种途径。

此外，可以在种子特定的相似模型训练的每个参数中使用多个种子客户。这限制了模型可以过度拟合的程度，从而限制了可以推断的用户相关数据量。因此，我们建议种子数据的最小大小为 500 个用户。

最后，一定不要向训练数据提供者提供用户级指标，这可以阻断成员身份推断攻击的另一种途径。

# Clean Rooms ML 的训练数据要求
<a name="ml-training-data-requirements"></a>

要成功创建相似模型，您的训练数据必须满足以下要求：
+ 训练数据必须采用 Parquet、CSV 或 JSON 格式。
**注意**  
不支持 Zstandard (ZSTD) 压缩的 Parquet 数据。
+ 您的训练数据必须编入 AWS Glue目录。有关更多信息，请参阅 AWS Glue 开发人员指南[中的 AWS Glue 数据目录入门](https://docs.aws.amazon.com//glue/latest/dg/start-data-catalog.html)。我们建议使用 AWS Glue 爬虫来创建表，因为架构是自动推断出来的。
+ 包含训练数据和种子数据的 Amazon S3 存储桶与您的其他 Clean Rooms 机器学习资源位于同一 AWS 区域。
+ 训练数据必须包含至少 100,000 个独立用户 IDs ，每个用户至少有两个项目互动。
+ 训练数据必须包含至少 100 万条记录。
+ [CreateTrainingDataset](https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_CreateTrainingDataset.html)操作中指定的架构必须与创建 AWS Glue 表时定义的架构保持一致。
+ 所提供的表中定义的必填字段是在 [CreateTrainingDataset](https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_CreateTrainingDataset.html) 操作中定义的。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/ml-training-data-requirements.html)
+ 或者，您最多可以提供 10 个分类或数值特征。

以下是 CSV 格式的有效训练数据集的示例

```
USER_ID,ITEM_ID,TIMESTAMP,EVENT_TYPE(CATEGORICAL FEATURE),EVENT_VALUE (NUMERICAL FEATURE)
196,242,881250949,click,15
186,302,891717742,click,13
22,377,878887116,click,10
244,51,880606923,click,20
166,346,886397596,click,10
```

# Clean Rooms ML 的种子数据要求
<a name="ml-seed-data-requirements"></a>

相似模型的种子数据可以直接来自 Amazon S3 存储桶，也可以来自 SQL 查询结果。

直接提供的种子数据必须满足以下要求：
+ 种子数据必须采用 JSON 行格式，并包含用户列表 IDs。
+ 种子大小应介于 25 到 500,000 个唯一用户之间 IDs。
+ 种子用户的最小数量必须与您在创建配置的受众模型时指定的最小匹配种子大小值相匹配。

以下是 CSV 格式的有效训练数据集的示例

```
{"user_id": "abc"}
{"user_id": "def"}
{"user_id": "ghijkl"}
{"user_id": "123"}
{"user_id": "456"}
{"user_id": "7890"}
```

# AWS Clean Rooms 机器学习模型评估指标
<a name="ml-metrics"></a>

Clean Rooms ML 计算*召回率*和*相关性分数*以确定模型的性能。召回率比较相似数据和训练数据之间的相似性。相关性分数用于确定受众规模应该有多大，而不是模型是否性能很好。

*召回率*是衡量相似细分与训练数据相似程度的公正标准。召回率是受众生成作业在种子受众中包含的训练数据样本中最相似用户的百分比（默认情况下，最相似百分比为 20％）。值范围为 0-1，值越大表示受众越好。召回值大致等于最大区间百分比就表示受众模型等同于随机选择。

我们认为这是比准确性、精度和 F1 分数更好的评估指标，因为 Clean Rooms ML 在构建模型时没有准确地标记真正的负面用户。

细分级*相关性分数* 是一个相似性指标，值范围从 -1（最不相似）到 1（最相似）。Clean Rooms ML 为不同的细分大小计算一组相关性分数，以帮助您确定数据的最佳细分大小。随着区段大小的增加，相关性分数会单调降低，因此，随着区段大小的增加，它可能与种子数据不太相似。在细分级相关性分数达到 0 时，模型预测相似细分中的所有用户来自与种子数据相同的分布。增加输出大小可能会包括相似细分中来自与种子数据不同的分布的用户。

相关性分数是在单个活动中标准化的，不应用于比较不同的活动。不应将相关性分数用作任何业务结果的单一来源证据，因为除了相关性外，这些分数还会受到多个复杂因素的影响，例如库存质量、库存类型、广告投放时间等。

相关性分数不应用于判断种子质量，而应用于判断它是否可以增加或减少。考虑以下示例：
+ 全部为正分 - 这表明预测为相似的输出用户比相似细分中包含的用户多。这对于属于大型市场的种子数据来说很常见，例如，过去一个月内购买过牙膏的每个人。我们建议查看较小的种子数据，例如，过去一个月内多次购买牙膏的每个人。
+ 全部为负分或您所需的相似细分大小为负分 - 这表明 Clean Rooms ML 预测在所需的相似细分大小中没有足够的相似用户。这可能是因为，种子数据太具体或市场太小。我们建议为种子数据应用更少的筛选条件，或者扩大市场。例如，如果原始种子数据是购买婴儿车和汽车座椅的客户，您可以将市场扩大到购买多种婴儿产品的客户。

训练数据提供者确定是否公开相关性分数以及计算相关性分数的桶区间。

# Clean Rooms ML 中的自定义模型
<a name="custom-models"></a>

借助 Clean Rooms ML，协作成员可以使用存储在 Amazon ECR 中的 dockerized 自定义模型算法来共同分析他们的数据。为此，*模型提供者*必须创建图像并将其存储在 Amazon ECR 中。按照 [Amazon Elastic Container Registry 用户指南](https://docs.aws.amazon.com/AmazonECR/latest/userguide/)中的步骤创建包含自定义 ML 模型的私有存储库。

协作中的任何成员都可以成为*模型提供者*，前提是他们拥有正确的权限。协作的所有成员都可以向模型贡献数据。在本指南中，提供数据的成员被称为*数据提供者*。创建协作的成员是协作创建*者*，该成员可以是*模型提供者，也可以是*数据提供**者之一，或者两者兼而有之。

以下主题描述了创建自定义 ML 模型所需的信息

**Topics**
+ [自定义 ML 建模先决条件](custom-model-prerequisites.md)
+ [训练容器的模型创作指南](custom-model-guidelines.md)
+ [推理容器的模型创作指南](inference-model-guidelines.md)
+ [接收模型日志和指标](custom-model-logs.md)

# 自定义 ML 建模先决条件
<a name="custom-model-prerequisites"></a>

在执行自定义 ML 建模之前，应考虑以下几点：
+ 确定是否将在协作中同时对训练过的模型进行模型训练和推理。
+ 确定每个协作成员将扮演的角色并为他们分配适当的能力。
  + 将该`CAN_QUERY`能力分配给将训练模型并对训练过的模型进行推理的成员。
  + 将分配`CAN_RECEIVE_RESULTS`给至少一名协作成员。
  + 为将分别接收训练模型导出或推理输出的成员分配`CAN_RECEIVE_MODEL_OUTPUT`或`CAN_RECEIVE_INFERENCE_OUTPUT`能力。如果您的用例需要这两种技能，则可以选择使用这两种技能。
+ 确定允许导出的训练模型工件或推理结果的最大大小。
+ 我们建议所有用户的角色都附加`CleanrooomsFullAccess`和`CleanroomsMLFullAccess`策略。使用自定义 ML 模型需要同时使用 AWS Clean Rooms 和 AWS Clean Rooms ML SDKs。
+ 请考虑以下有关 IAM 角色的信息。
  + 所有数据提供者都必须具有服务访问角色， AWS Clean Rooms 允许从其 AWS Glue 目录和表以及底层 Amazon S3 位置读取数据。这些角色与 SQL 查询所需的角色类似。这允许您使用该`CreateConfiguredTableAssociation`操作。有关更多信息，请参阅 [创建服务角色以创建已配置的表关联](ml-roles.md#ml-roles-custom-configure-table)。
  + 所有想要接收指标的成员都必须具有服务访问角色，允许他们写入 CloudWatch 指标和日志。在模型训练和推理 AWS 账户 期间，Clean Rooms ML 使用此角色将所有模型指标和日志写入成员的指标。我们还提供隐私控制，以确定哪些成员有权访问指标和日志。这允许您使用该`CreateMLConfiguration`操作。有关更多信息，请参阅[为自定义 ML 建模创建服务角色-机器学习配置](ml-roles.md#ml-roles-custom-configure)。

    接收结果的成员必须为服务访问角色提供写入其 Amazon S3 存储桶的权限。此角色允许 Clean Rooms ML 将结果（经过训练的模型工件或推理结果）导出到 Amazon S3 存储桶。这允许您使用该`CreateMLConfiguration`操作。有关更多信息，请参阅 [为自定义 ML 建模创建服务角色-机器学习配置](ml-roles.md#ml-roles-custom-configure)。
  + 模型提供者必须为服务访问角色提供读取其 Amazon ECR 存储库和图像的权限。这允许您使用该`CreateConfigureModelAlgorithm`操作。有关更多信息，请参阅 [创建服务角色以提供自定义 ML 模型](ml-roles.md#ml-roles-custom-model-provider)。
  + 创建`MLInputChannel`以生成用于训练或推理的数据集的成员必须提供允许 Clean Rooms ML 在中 AWS Clean Rooms执行 SQL 查询的服务访问角色。这允许您使用`CreateTrainedModel`和`StartTrainedModelInferenceJob`操作。有关更多信息，请参阅 [创建用于查询数据集的服务角色](ml-roles.md#ml-roles-custom-query-dataset)。
+ 模型作者应遵循[训练容器的模型创作指南](custom-model-guidelines.md)和[推理容器的模型创作指南接收模型日志和指标](inference-model-guidelines.md)，以确保模型输入和输出按预期进行配置 AWS Clean Rooms。

# 训练容器的模型创作指南
<a name="custom-model-guidelines"></a>

本节详细介绍了模型提供者在为 Clean Rooms ML 创建自定义 ML 模型算法时应遵循的指南。
+ 使用 SageMaker AI 训练支持的相应容器基础镜像，如 [SageMaker AI 开发者](https://docs.aws.amazon.com/sagemaker/latest/dg-ecr-paths/sagemaker-algo-docker-registry-paths.html)指南中所述。以下代码允许您从公共 SageMaker AI 终端节点提取支持的容器基础镜像。

  ```
  ecr_registry_endpoint='763104351884.dkr.ecr.$REGION.amazonaws.com'
  base_image='pytorch-training:2.3.0-cpu-py311-ubuntu20.04-sagemaker'
  aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ecr_registry_endpoint
  docker pull $ecr_registry_endpoint/$base_image
  ```
+ 在本地创作模型时，请确保满足以下条件，以便可以在本地、开发实例、在自己的 SageMaker AI Training 和 Clean Roo AWS 账户 ms ML 上测试模型。
  + 我们建议编写一个训练脚本，通过各种环境变量访问有关训练环境的有用属性。Clean Rooms ML 使用以下参数来调用模型代码的训练：`SM_MODEL_DIR``SM_OUTPUT_DIR``SM_CHANNEL_TRAIN`、、和`FILE_FORMAT`。Clean Rooms ML 使用这些默认值在自己的执行环境中使用来自各方的数据训练机器学习模型。
  + Clean Rooms ML 通过 docker 容器中的`/opt/ml/input/data/channel-name`目录提供您的训练输入频道。每个 ML 输入通道均根据`CreateTrainedModel`请求中`channel_name`提供的相应通道进行映射。

    ```
    parser = argparse.ArgumentParser()# Data, model, and output directories
    
    parser.add_argument('--model_dir', type=str, default=os.environ.get('SM_MODEL_DIR', "/opt/ml/model"))
    parser.add_argument('--output_dir', type=str, default=os.environ.get('SM_OUTPUT_DIR', "/opt/ml/output/data"))
    parser.add_argument('--train_dir', type=str, default=os.environ.get('SM_CHANNEL_TRAIN', "/opt/ml/input/data/train"))
    parser.add_argument('--train_file_format', type=str, default=os.environ.get('FILE_FORMAT', "csv"))
    ```
  + 确保您能够根据模型代码中使用的协作者架构生成合成数据集或测试数据集。
  + 在将模型算法与 AWS Clean Rooms 协作关联 AWS 账户 之前，请确保您可以自己运行 SageMaker AI 训练作业。

    以下代码包含与本地测试、 SageMaker AI 训练环境测试和 Clean Rooms ML 兼容的示例 Docker 文件

    ```
    FROM  763104351884.dkr.ecr.us-west-2.amazonaws.com/pytorch-training:2.3.0-cpu-py311-ubuntu20.04-sagemaker
    MAINTAINER $author_name
    
    ENV PYTHONDONTWRITEBYTECODE=1 \
        PYTHONUNBUFFERED=1 \
        LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/usr/local/lib"
    
    ENV PATH="/opt/ml/code:${PATH}"
    
    # this environment variable is used by the SageMaker PyTorch container to determine our user code directory
    ENV SAGEMAKER_SUBMIT_DIRECTORY /opt/ml/code
    
    # copy the training script inside the container
    COPY train.py /opt/ml/code/train.py
    # define train.py as the script entry point
    ENV SAGEMAKER_PROGRAM train.py
    ENTRYPOINT ["python", "/opt/ml/code/train.py"]
    ```
+ 为了最好地监控容器故障，我们建议导出日志并出于故障原因进行调试。作为`GetTrainedModel`响应，Clean Rooms ML 返回了该文件中的前 1024 个字符`StatusDetails`。
+ 完成所有模型更改并准备好在 SageMaker AI 环境中对其进行测试后，请按提供的顺序运行以下命令。

  ```
  export ACCOUNT_ID=xxx
  export REPO_NAME=xxx
  export REPO_TAG=xxx
  export REGION=xxx
  
  docker build -t $ACCOUNT_ID.dkr.ecr.us-west-2.amazonaws.com/$REPO_NAME:$REPO_TAG
  
  # Sign into AWS $ACCOUNT_ID/ Run aws configure
  # Check the account and make sure it is the correct role/credentials
  aws sts get-caller-identity
  aws ecr create-repository --repository-name $REPO_NAME --region $REGION
  aws ecr describe-repositories --repository-name $REPO_NAME --region $REGION
  
  # Authenticate Doker
  aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com
  
  # Push To ECR Images
  docker push  $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com$REPO_NAME:$REPO_TAG
  
  # Create Sagemaker Training job
  # Configure the training_job.json with
  # 1. TrainingImage
  # 2. Input DataConfig
  # 3. Output DataConfig
  aws sagemaker create-training-job --cli-input-json file://training_job.json --region $REGION
  ```

  在 SageMaker AI 任务完成并且您对模型算法感到满意后，您可以使用 AWS Clean Rooms ML 注册 Amazon ECR 注册表。使用`CreateConfiguredModelAlgorithm`操作注册模型算法并将其`CreateConfiguredModelAlgorithmAssociation`与协作关联。

# 推理容器的模型创作指南
<a name="inference-model-guidelines"></a>

本节详细介绍了模型提供者在为 Clean Rooms ML 创建推理算法时应遵循的指南。
+ [按照《 SageMaker AI 开发者指南》中所述，使用支持人工智能推理的相应容器基础镜像。SageMaker ](https://docs.aws.amazon.com/sagemaker/latest/dg-ecr-paths/sagemaker-algo-docker-registry-paths.html)以下代码允许您从公共 SageMaker AI 终端节点提取支持的容器基础镜像。

  ```
  ecr_registry_endpoint='763104351884.dkr.ecr.$REGION.amazonaws.com'
  base_image='pytorch-inference:2.3.0-cpu-py311-ubuntu20.04-sagemaker'
  aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ecr_registry_endpoint
  docker pull $ecr_registry_endpoint/$base_image
  ```
+ 在本地创作模型时，请确保满足以下条件，以便可以在本地、开发实例、您的 SageMaker AI Batch Transform 和 Clean Rooms ML 上测试模型。 AWS 账户
  + Clean Rooms ML 通过 docker 容器中的`/opt/ml/model`目录使推理中的模型工件可供推理代码使用。
  + Clean Rooms ML 按行拆分输入，使用`MultiRecord`批处理策略，并在每条转换后的记录的末尾添加一个换行符。
  + 确保您能够根据将在模型代码中使用的协作者的架构生成合成或测试推理数据集。
  + 在将模型算法与 AWS Clean Rooms 协作关联 AWS 账户 之前，请确保您可以自己运行 SageMaker AI 批量转换作业。

    以下代码包含与本地测试、 SageMaker AI 转换环境测试和 Clean Rooms ML 兼容的示例 Docker 文件

    ```
    FROM 763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-inference:1.12.1-cpu-py38-ubuntu20.04-sagemaker
    
    ENV PYTHONUNBUFFERED=1
    
    COPY serve.py /opt/ml/code/serve.py
    COPY inference_handler.py /opt/ml/code/inference_handler.py
    COPY handler_service.py /opt/ml/code/handler_service.py
    COPY model.py /opt/ml/code/model.py
    
    RUN chmod +x /opt/ml/code/serve.py
    
    ENTRYPOINT ["/opt/ml/code/serve.py"]
    ```
+ 完成所有模型更改并准备好在 SageMaker AI 环境中对其进行测试后，请按提供的顺序运行以下命令。

  ```
  export ACCOUNT_ID=xxx
  export REPO_NAME=xxx
  export REPO_TAG=xxx
  export REGION=xxx
  
  docker build -t $ACCOUNT_ID.dkr.ecr.us-west-2.amazonaws.com/$REPO_NAME:$REPO_TAG
  
  # Sign into AWS $ACCOUNT_ID/ Run aws configure
  # Check the account and make sure it is the correct role/credentials
  aws sts get-caller-identity
  aws ecr create-repository --repository-name $REPO_NAME --region $REGION
  aws ecr describe-repositories --repository-name $REPO_NAME --region $REGION
  
  # Authenticate Docker
  aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com
  
  # Push To ECR Repository
  docker push $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com$REPO_NAME:$REPO_TAG
  
  # Create Sagemaker Model
  # Configure the create_model.json with
  # 1. Primary container - 
      # a. ModelDataUrl - S3 Uri of the model.tar from your training job
  aws sagemaker create-model --cli-input-json file://create_model.json --region $REGION
  
  # Create Sagemaker Transform Job
  # Configure the transform_job.json with
  # 1. Model created in the step above 
  # 2. MultiRecord batch strategy
  # 3. Line SplitType for TransformInput
  # 4. AssembleWith Line for TransformOutput
  aws sagemaker create-transform-job --cli-input-json file://transform_job.json --region $REGION
  ```

  在 SageMaker AI 任务完成并且您对批量转换感到满意后，您可以使用 AWS Clean Rooms ML 注册 Amazon ECR 注册表。使用`CreateConfiguredModelAlgorithm`操作注册模型算法并将其`CreateConfiguredModelAlgorithmAssociation`与协作关联。

# 接收模型日志和指标
<a name="custom-model-logs"></a>

要接收来自自定义模型训练或推理的日志和指标，成员必须[创建具有提供必要 CloudWatch 权限的有效角色的 ML 配置](https://docs.aws.amazon.com/clean-rooms/latest/userguide/create-custom-ml-collaboration.html)（请参阅[为自定义 ML 建模创建服务角色——机器学习配置](https://docs.aws.amazon.com/clean-rooms/latest/userguide/ml-roles.html#ml-roles-custom-configure)）。

**系统指标**

训练和推理的系统指标（例如 CPU 和内存利用率）通过有效的机器学习配置发布给所有成员。随着任务的进展，可以分别通过`/aws/cleanroomsml/TrainedModels`或`/aws/cleanroomsml/TrainedModelInferenceJobs`命名空间中的 CloudWatch指标查看这些指标。

**模型日志**

模型日志的访问权限由每个已配置的模型算法的隐私配置策略提供。模型作者在将配置的模型算法（通过控制台或 `CreateConfiguredModelAlgorithmAssociation` API）关联到协作时设置隐私配置策略。设置隐私配置策略可控制哪些成员可以接收模型日志。

此外，模型作者可以在隐私配置策略中设置过滤器模式来过滤日志事件。模型容器发送到`stdout`或`stderr`且符合筛选模式（如果已设置）的所有 CloudWatch 日志都将发送到 Amazon Logs。模型日志分别在 CloudWatch 日志组`/aws/cleanroomsml/TrainedModels`或`/aws/cleanroomsml/TrainedModelInferenceJobs`中可用。

**自定义指标**

在配置模型算法（通过控制台或 `CreateConfiguredModelAlgorithm` API）时，模型作者可以在输出日志中提供要搜索的特定指标名称和正则表达式语句。这些可以在任务进行时通过`/aws/cleanroomsml/TrainedModels`命名空间中的 CloudWatch 指标进行查看。关联已配置的模型算法时，模型作者可以在指标隐私配置中设置可选的噪声级别，以避免输出原始数据，同时仍然提供对自定义指标趋势的可见性。如果设置了噪音水平，则指标将在作业结束时发布，而不是实时发布。

# 加密计算 Clean Rooms
<a name="crypto-computing"></a>

加密计算 Clean Rooms (C3R) 是一种除了[分析 AWS Clean Rooms](analysis-rules.md)规则之外还可以使用的功能。借助 C3R，组织可以将敏感数据整合在一起，从数据分析中获得新的见解，同时以加密方式限制任何一方在流程中可以了解到的信息。C3R 可供想要协作处理其敏感数据但只需要在云中使用加密数据的两方或多方使用。

C3R 加密客户端是一种客户端加密工具，您可以使用它来[加密](glossary.md#glossary-encryption)数据以供使用。 AWS Clean Rooms使用 C3R 加密客户端时，数据在协作中使用时仍会受到加密保护。 AWS Clean Rooms 与常规 AWS Clean Rooms 协作一样，输入数据是关系数据库表，计算以 SQL 查询表示。但是，C3R 仅支持对加密数据的有限 SQL 查询子集。

具体而言，C3R 支持 SQL JOIN 以及 SELECT 关于受加密保护的数据的声明。输入表中的每列只能用于以下 SQL 语句类型之一：
+ 受加密保护的列，可用于 JOIN 语句被称为 **fingerprint 列**。
+ 受加密保护的列，可用于 SELECT 语句被称为 **sealed 列**。
+ 未受加密保护的列，无法用于 JOIN 或 SELECT 语句被称为 **cleartext 列**。

在某些情况下，GROUP BY 支持语句 fingerprint 列。有关更多信息，请参阅 [Fingerprint 列](crypto-computing-column-types.md#fingerprint-columns)。目前，C3R 不支持在加密数据上使用其他 SQL 结构，例如 WHERE 子句或聚合函数，比如 SUM 以及 AVERAGE, 即使相关分析规则允许这样做.

C3R 旨在保护表中各个单元格中的数据。使用 C3R 的默认配置，当内容在 AWS Clean Rooms中使用时，客户通过协作向第三方提供的底层数据将保持加密。C3R 对所有人使用行业标准 AES-GCM 加密 sealed 列和行业标准的伪随机函数，称为基于哈希的消息身份验证码 (HMAC)，用于保护 fingerprint 列。

尽管 C3R 会对表中的数据进行加密，但仍可以推断出以下信息：
+ 有关表本身的信息，包括表中的列数、列名和行数。
+ 与大多数标准加密形式一样，C3R 不会尝试隐藏加密值的长度。C3R 确实提供了填充加密值以隐藏明文确切长度的功能。但是，仍然可以向另一方揭示每列明文长度的上限。
+ 日志级别的信息，例如何时将特定行添加到加密的 C3R 表中。

有关 C3R 的更多信息，请参阅以下主题。

**Topics**
+ [使用 Clean Rooms 加密计算时的注意事项](crypto-computing-considerations.md)
+ [Clean Rooms 加密计算中支持的文件和数据类型](crypto-computing-file-types.md)
+ [Clean Rooms 加密计算中的列名](crypto-computing-column-names.md)
+ [Clean Rooms 加密计算中的列类型](crypto-computing-column-types.md)
+ [加密计算参数](crypto-computing-parameters.md)
+ [Clean Rooms 加密计算中的可选标志](crypto-computing-optional-flags.md)
+ [使用 Clean Rooms 加密计算进行查询](crypto-computing-queries.md)
+ [C3R 加密客户端指南](crypto-computing-guidelines.md)

# 使用 Clean Rooms 加密计算时的注意事项
<a name="crypto-computing-considerations"></a>

Clean Rooms 加密计算 (C3R) 旨在最大限度地保护数据。但是，某些使用案例可能会受益于较低级别的数据保护，以换取额外的功能。您可以通过修改 C3R 最安全的配置来做出这些特定的权衡。作为客户，您应该了解这些权衡，并确定它们是否适合您的使用案例。要考虑的权衡包括以下内容：

**Topics**
+ [允许在表中混合 cleartext 和加密数据](#allow-mixed-plaintext-and-encrypted-data)
+ [允许 fingerprint 列中有重复值](#allow-repeated-values)
+ [放宽对 fingerprint 列命名方式的限制](#loose-restrictions-on-join-column-names)
+ [确定 NULL 值的表示方式](#determine-null-values)

有关如何为这些场景设置参数的更多信息，请参阅[加密计算参数](crypto-computing-parameters.md)。

## 允许在表中混合 cleartext 和加密数据
<a name="allow-mixed-plaintext-and-encrypted-data"></a>

对所有数据进行客户端加密可最大限度地保护数据。但是，这限制了某些类型的查询（例如，SUM 聚合函数）。允许 cleartext 数据的风险在于，任何有权访问加密表的人都可以推断出一些有关加密值的信息。这可以通过对 cleartext 和关联数据进行统计分析来实现。

例如，假设您的列为 `City` 和 `State`。`City` 列为 cleartext，`State` 列加密。当您看到 `City` 列中的 `Chicago` 值时，这有助于您确定 `State` 很有可能是 `Illinois`。相比之下，如果一列是 `City`，另一列是 `EmailAddress`，则 cleartext `City` 不太可能揭示加密 `EmailAddress` 的任何信息。

有关此场景的参数的更多信息，请参阅[允许 cleartext 列参数](crypto-computing-parameters.md#parameter-allowcleartext)。

## 允许 fingerprint 列中有重复值
<a name="allow-repeated-values"></a>

对于最安全的方法，我们假设任何 fingerprint 列都只包含一个变量实例。fingerprint 列中的任何项目都不能重复。C3R 加密客户端将这些 cleartext 值映射为与随机值无法区分的唯一值。因此，不可能从这些随机值中推断出 cleartext 信息。

fingerprint 列中有重复值的风险在于，重复的值会导致重复的随机值。因此，从理论上讲，任何有权访问加密表的人都可以对可能揭示 cleartext 值信息的 fingerprint 列进行统计分析。

同样，假设 fingerprint 列是 `State`，并且表中的每一行都对应一个美国家庭。通过频率分析，人们很有可能推断出哪个州是 `California`，哪个州是 `Wyoming`。这种推断是可能的，因为 `California` 的居民人数远远超过 `Wyoming`。相比之下，假设 fingerprint 列位于家庭标识符上，在包含数百万个条目的数据库中，每个家庭出现 1 到 4 次。频率分析不太可能揭示任何有用的信息。

有关此场景的参数的更多信息，请参阅[“允许重复”参数](crypto-computing-parameters.md#parameter-allowduplicates)。

## 放宽对 fingerprint 列命名方式的限制
<a name="loose-restrictions-on-join-column-names"></a>

默认情况下，我们假设当使用加密 fingerprint 列联接两个表时，这些列在每个表中的名称相同。此结果的技术原因是，默认情况下，我们派生出不同的加密密钥来加密每个 fingerprint 列。该密钥源自协作共享密钥和列名的组合。如果我们尝试联接具有不同列名的两列，则会派生出不同的密钥，并且无法计算出有效的联接。

要解决这个问题，可以关闭从每个列名派生密钥的功能。然后，C3R 加密客户端对所有 fingerprint 列使用一个派生密钥。风险在于可以进行另一种可能揭示信息的频率分析。

让我们再次以 `City` 和 `State` 为例。如果我们为每个 fingerprint 列派生相同的随机值（不包含列名）。`New York` 在 `City` 和 `State` 列中的随机值相同。纽约是美国为数不多的 `City` 名称与 `State` 名称相同的城市之一。相比之下，如果数据集的每一列都有完全不同的值，则不会泄露任何信息。

有关此场景的参数的更多信息，请参阅[“允许对具有不同名称的列进行 JOIN”参数](crypto-computing-parameters.md#parameter-allowjoin)。

## 确定 NULL 值的表示方式
<a name="determine-null-values"></a>

您可以选择是否像处理其他值一样对 NULL 值进行加密处理（加密和 HMAC）。如果您不像处理其他值一样处理 NULL 值，可能会揭示信息。

例如，假设 cleartext 中 `Middle Name` 列中的 NULL 表示没有中间名的人。如果您不加密这些值，则会泄露加密表中哪些行用于没有中间名的人。对于某些人群中的某些人来说，这些信息可能是一个识别信号。但是，如果您对 NULL 值进行加密处理，某些 SQL 查询的行为就会有所不同。例如，GROUP BY 子句不会将 fingerprint 列中的 fingerprintNULL 值分组在一起。

有关此场景的参数的更多信息，请参阅[“保留 NULL 值”参数](crypto-computing-parameters.md#parameter-preservenulls)。

# Clean Rooms 加密计算中支持的文件和数据类型
<a name="crypto-computing-file-types"></a>

C3R 加密客户端可识别以下文件类型：
+ CSV 文件
+ Parquet 文件

您可以在 C3R 加密客户端中使用 `--fileFormat` 标志来明确指定文件格式。如果明确指定，则文件格式不取决于文件扩展名。

**Topics**
+ [CSV 文件](#csv-file-type)
+ [Parquet 文件](#parquet-file-type)
+ [加密非字符串值](#encrypt-non-string-values)

## CSV 文件
<a name="csv-file-type"></a>

假定扩展名为 .csv 的文件采用 CSV 格式并包含 UTF-8 编码的文本。C3R 加密客户端将所有值视为字符串。

### .csv 文件中支持的属性
<a name="csv-properties"></a>

C3R 加密客户端要求 .csv 文件具有以下属性：
+ 可能包含也可能不包含唯一命名每列的初始标题行。
+ 逗号分隔。（目前，不支持自定义分隔符。）
+ UTF-8 编码的文本。

#### 从 .csv 条目中修剪空格
<a name="whitespace-trimming"></a>

.csv 条目中的前导和尾部空格都会被修剪。

#### .csv 文件的自定义 NULL 编码
<a name="custom-null-encoding"></a>

.csv 文件可以使用自定义 NULL 编码。

使用 C3R 加密客户端，您可以使用 `--csvInputNULLValue=<csv-input-null>` 标志为输入数据中的 NULL 条目指定自定义编码。通过使用 `--csvOutputNULLValue=<csv-output-null>` 标志，C3R 加密客户端可以在生成的输出文件中为 NULL 条目使用自定义编码。

**注意**  
NULL 条目被认为*缺少* 内容，特别是在 SQL 表等更丰富的表格格式的上下文中。尽管由于历史原因 .csv 并不明确支持这种描述，但通常的惯例是将仅包含空格的空条目视为 NULL。因此，这是 C3R 加密客户端的默认行为，可以根据需要对其进行自定义。

### C3R 如何解释 .csv 条目
<a name="interpretation-csv-entries"></a>

下表举例说明了如何根据为 `--csvInputNULLValue=<csv-input-null>` 和 `--csvOutputNULLValue=<csv-output-null>` 标志提供的值（如果有）编组 .csv 条目（为清楚起见，cleartext 至 cleartext）。在 C3R 解释任何值的含义之前，将修剪引号之外的前导和尾部空格。


| `<csv-input-null>` | `<csv-output-null>` | 输入条目 | 输出条目 | 
| --- |--- |--- |--- |
| 无 | 无 | ,AnyProduct, | ,AnyProduct, | 
| 无 | 无 | , AnyProduct , | ,AnyProduct, | 
| 无 | 无 | ,"AnyProduct", | ,AnyProduct, | 
| 无 | 无 | , "AnyProduct" , | ,AnyProduct, | 
| 无 | 无 | ,, | ,, | 
| 无 | 无 | , , | ,, | 
| 无 | 无 | ,"", | ,, | 
| 无 | 无 | ," ", | ," ", | 
| 无 | 无 | , " " , | ," ", | 
| "AnyProduct" | "NULL" | ,AnyProduct, | ,NULL, | 
| "AnyProduct" | "NULL" | , AnyProduct , | ,NULL, | 
| "AnyProduct" | "NULL" | ,"AnyProduct", | ,NULL, | 
| "AnyProduct" | "NULL" | , "AnyProduct" , | ,NULL, | 
| 无 | "NULL" | ,, | ,NULL, | 
| 无 | "NULL" | , , | ,NULL, | 
| 无 | "NULL" | ,"", | ,NULL, | 
| 无 | "NULL" | ," ", | ," ", | 
| 无 | "NULL" | , " " , | ," ", | 
| "" | "NULL" | ,, | ,NULL, | 
| "" | "NULL" | , , | ,NULL, | 
| "" | "NULL" | ,"", | ,"", | 
| "" | "NULL" | ," ", | ," ", | 
| "" | "NULL" | , " " , | ," ", | 
| "\$1"\$1"" | "NULL" | ,, | ,, | 
| "\$1"\$1"" | "NULL" | , , | ,, | 
| "\$1"\$1"" | "NULL" | ,"", | ,NULL, | 
| "\$1"\$1"" | "NULL" | ," ", | ," ", | 
| "\$1"\$1"" | "NULL" | , " " , | ," ", | 

### 不带标题的 CSV 文件
<a name="csv-file-no-headers"></a>

源 .csv 文件不必在第一行中包含标题来唯一命名每列。但是，没有标题行的 .csv 文件需要位置加密架构。需要的是位置加密架构，而不是带标题行的 .csv 文件和 Parquet 文件使用的典型映射架构。

位置加密架构按位置而不是按名称指定输出列。映射加密架构将源列名映射到目标列名。有关更多信息，包括两种架构格式的详细讨论和示例，请参阅[映射和定位表架构](create-schema.md#mapped-and-positional-schemas)。

## Parquet 文件
<a name="parquet-file-type"></a>

假定扩展名为 .parquet 的文件采用 Apache Parquet 格式。

### 支持的 Parquet 数据类型
<a name="supported-parquet-data-types"></a>

C3R 加密客户端可以在表示 AWS Clean Rooms支持的数据类型的 Parquet 文件中处理任何非复杂（即基本类型）数据。

但是，只能将字符串列用于 sealed 列。

支持以下 Parquet 数据类型：
+ 带以下逻辑注释的 `Binary` 基本类型：
  + 如果已设置 `--parquetBinaryAsString`（`STRING` 数据类型），则为 None
  + `Decimal(scale, precision)`（`DECIMAL` 数据类型）
  + `String`（`STRING` 数据类型）
+ 不带逻辑注释的 `Boolean` 基本数据类型（`BOOLEAN` 数据类型）
+ 不带逻辑注释的 `Double` 基本数据类型（`DOUBLE` 数据类型）
+ 带 `Decimal(scale, precision)` 逻辑注释的 `Fixed_Len_Binary_Array` 基本类型（`DECIMAL` 数据类型）
+ 不带逻辑注释的 `Float` 基本数据类型（`FLOAT` 数据类型）
+ 带以下逻辑注释的 `Int32` 基本类型：
  + 无（`INT` 数据类型）
  + `Date`（`DATE` 数据类型）
  + `Decimal(scale, precision)`（`DECIMAL` 数据类型）
  + `Int(16, true)`（`SMALLINT` 数据类型）
  + `Int(32, true)`（`INT` 数据类型）
+ 带以下逻辑注释的 `Int64` 基本数据类型：
  + 无（`BIGINT` 数据类型）
  + `Decimal(scale, precision)`（`DECIMAL` 数据类型）
  + `Int(64, true)`（`BIGINT` 数据类型）
  + `Timestamp(isUTCAdjusted, TimeUnit.MILLIS)`（`TIMESTAMP` 数据类型）
  + `Timestamp(isUTCAdjusted, TimeUnit.MICROS)`（`TIMESTAMP` 数据类型）
  + `Timestamp(isUTCAdjusted, TimeUnit.NANOS)`（`TIMESTAMP` 数据类型）

## 加密非字符串值
<a name="encrypt-non-string-values"></a>

当前，sealed 列仅支持字符串值。

对于 .csv 文件，C3R 加密客户端会将所有值视为 UTF-8 编码的文本，并且在加密之前不会尝试对其进行不同的解释。

对于指纹列，类型被分为等价类。等价类是一组数据类型，可以通过代表性数据类型明确比较其是否相等。

等价类允许将相同的指纹分配给相同的语义值，而不管原始表示形式如何。但是，两个等价类中的相同值不会生成相同的指纹列。

例如，无论 `INTEGRAL` 值 `42` 最初是 `SMALLINT`、`INT` 还是 `BIGINT`，都将为其分配相同的指纹。此外，`INTEGRAL` 值 `0` 永远不会与 `BOOLEAN` 值 `FALSE` 匹配（由值 `0` 表示）。

指纹列支持以下等价类和相应 AWS Clean Rooms 的数据类型：


| 等价类 | 支持的 AWS Clean Rooms 数据类型 | 
| --- | --- | 
| BOOLEAN | BOOLEAN | 
| DATE | DATE | 
| INTEGRAL | BIGINT, INT, SMALLINT | 
|  STRING | CHAR, STRING, VARCHAR | 

# Clean Rooms 加密计算中的列名
<a name="crypto-computing-column-names"></a>

默认情况下，在 Clean Rooms 加密计算中，列的名称很重要。

如果**允许对具有不同名称的列进行 JOIN** 参数的值为 **false**，则在加密 fingerprint 列时将使用列名。因此，默认情况下，协作者必须事先进行协调，并对将在查询中使用 JOIN 语句的数据使用相同的目标列名称。默认情况下，为 JOIN 加密的列如果名称不同，就不能成功地对任何值进行 JOIN。

如果**允许对具有不同名称的列进行 JOIN** 参数的值为 **true**，则跨加密为 fingerprint 列的列的 JOIN 语句会成功。使用此参数加密数据可能允许对 cleartext 值进行一些推断。例如，如果某行的 `City` 列和 `State` 列中都具有相同的 HMAC 散列消息认证码值，则该值可能为 `New York`。

## 列标题名称的标准化
<a name="column-header-names-normalization"></a>

列标题名称由 C3R 加密客户端进行标准化。所有前导和尾随的空格都将被删除，转换后的输出将列名改为小写。

标准化应用于可能受列名影响的所有其他计算或其他运算。发出的输出文件仅包含标准化名称。

# Clean Rooms 加密计算中的列类型
<a name="crypto-computing-column-types"></a>

本主题提供有关 Clean Rooms 加密计算中列类型的信息。

**Topics**
+ [Fingerprint 列](#fingerprint-columns)
+ [密封列](#sealed-columns)
+ [Cleartext 列](#cleartext-columns)

## Fingerprint 列
<a name="fingerprint-columns"></a>

*Fingerprint 列*是在 JOIN 语句中使用的受加密保护的列。

fingerprint 列中的数据无法解密。只有密封列中的数据才能解密。

Fingerprint 列只能在以下 SQL 子句和函数中使用：
+ JOIN (INNER, OUTER, LEFT, RIGHT, or FULL) 与其他 fingerprint 列对比：
  + 如果将 `allowJoinsOnColumnsWithDifferentNames` 参数的值设置为 `false`，则 JOIN 的两个 fingerprint 列的名称也必须相同。
+ `SELECT COUNT()`
+ `SELECT COUNT(DISTINCT )`
+ `GROUP BY`（仅当协作将 `preserveNulls` 参数的值设置为 `true` 时才使用。）

违反这些限制条件的查询可能会生成不正确的结果。

## 密封列
<a name="sealed-columns"></a>

*密封列* 是 SELECT 语句中使用的通过加密保护的列。

密封列只能在以下 SQL 子句和函数中使用：
+ `SELECT`
+ `SELECT ... AS`
+ `SELECT COUNT()`
**注意**  
不支持 `SELECT COUNT(DISTINCT )`。

违反这些限制条件的查询可能会生成不正确的结果。

### 加密前为 sealed 列填充数据
<a name="padding-data"></a>

当您指定列应该是 sealed 列时，C3R 会询问您要选择哪种*填充*。加密前填充数据是可选的。如果不使用填充（填充类型为 `none`），则加密数据的长度表示 cleartext 的大小。在某些情况下，cleartext 的大小可能会暴露明文。如果使用填充（填充类型为 `fixed` 或 `max`），则先将所有值填充到常见大小，然后再加密。使用填充时，加密数据的长度除了给出其大小的上限外，不提供有关原始 cleartext 长度的信息。

如果要为列填充并且已知该列中数据的最大字节长度，请使用 `fixed` 填充。使用至少与该列中最长值的字节长度一样大的 `length` 值。

**注意**  
如果值长于提供的 `length` 值，则会发生错误并导致加密失败。

如果要为列填充并且未知该列中数据的最大字节长度，请使用 `max` 填充。这种填充模式将所有数据填充到最长值的长度加上额外的 `length` 字节。

**注意**  
您可能需要批量加密数据，或者定期使用新数据更新表。请注意，`max` 填充会将条目填充到给定批次中最长的明文条目的长度（加 `length` 字节）。这意味着加密文字长度可能因批次而异。因此，如果您知道列的最大字节长度，则应使用 `fixed` 而不是 `max`。

## Cleartext 列
<a name="cleartext-columns"></a>

*Cleartext 列*是在 JOIN 或 SELECT 语句中使用的未受加密保护的列。

Cleartext 列可以用于 SQL 查询的任何部分。

# 加密计算参数
<a name="crypto-computing-parameters"></a>

在[创建协作](create-collaboration.md)时，可使用 Clean Rooms 加密计算 (C3R) 为协作提供加密计算参数。您可以使用 AWS Clean Rooms 控制台或 `CreateCollaboration` API 操作创建协作。在控制台中，启用**支持加密计算**选项后，可以为**加密计算参数**中的参数设置值。有关更多信息，请参阅以下主题。

**Topics**
+ [允许 cleartext 列参数](#parameter-allowcleartext)
+ [“允许重复”参数](#parameter-allowduplicates)
+ [“允许对具有不同名称的列进行 JOIN”参数](#parameter-allowjoin)
+ [“保留 NULL 值”参数](#parameter-preservenulls)

## 允许 cleartext 列参数
<a name="parameter-allowcleartext"></a>

在控制台中，您可以在[创建协作](create-collaboration.md)时设置**允许 cleartext 列**参数，以指定是否允许在包含加密数据的表中包含 cleartext 数据。

下表描述了**允许 cleartext 列**参数的值。


| 参数值 | 说明 | 
| --- | --- | 
| 否 |  加密表中不允许有 Cleartext 列。所有数据都受到加密保护。  | 
| 是 |  加密表中允许有 Cleartext 列。 Cleartext 列不受加密保护，包含为 cleartext。您应该注意行中的 cleartext 数据可能揭示了表中其他数据的哪些信息。 要在特定列上运行 SUM 或 AVG，这些列必须是 cleartext。  | 

使用 `CreateCollaboration` API 操作，对于 `dataEncryptionMetadata` 参数，您可以将 `allowCleartext` 的值设置为 `true` 或 `false`。有关 API 操作的更多信息，请参阅 [AWS Clean Rooms API 参考](https://docs.aws.amazon.com/clean-rooms/latest/apireference/Welcome.html)。

Cleartext 列对应于按表特定架构分类为 cleartext 的列。这些列中的数据未加密，可以以任何方式使用。 Cleartext如果需要比加密列或fingerprint列所允许的更大的灵活性， and/or 则如果数据不敏感，则sealed列可能很有用。

## “允许重复”参数
<a name="parameter-allowduplicates"></a>

在控制台中，您可以在[创建协作](create-collaboration.md)时设置**允许重复**参数，以指定为 JOIN 查询加密的列是否可以包含重复的非 NULL 值。

**重要**  
**允许重复**、[**允许对不同名称列进行 JOIN**](#parameter-allowjoin) 和[**保留 NULL 值**](#parameter-preservenulls)参数具有单独但相关的效果。

下表描述了**允许重复**参数的值。


| 参数值 | 说明 | 
| --- | --- | 
| 否  |  fingerprint 列中不允许有重复的值。单个 fingerprint 列中的所有值都必须是唯一的。  | 
| 是 |  fingerprint 列中允许有重复的值。 如果需要联接具有重复值的列，请将此值设置为**是**。如果设置为**是**，则 C3R 表或结果的 fingerprint 列中出现的频率模式可能意味着有关 cleartext 数据结构的一些其他信息。  | 

使用 `CreateCollaboration` API 操作，对于 `dataEncryptionMetadata` 参数，您可以将 `allowDuplicates` 的值设置为 `true` 或 `false`。有关 API 操作的更多信息，请参阅 [AWS Clean Rooms API 参考](https://docs.aws.amazon.com/clean-rooms/latest/apireference/Welcome.html)。

默认情况下，如果必须在 JOIN 查询中使用加密数据，则 C3R 加密客户端要求这些列没有重复值。此要求是为了加强数据保护。这种行为可以帮助确保无法观察到数据中的重复模式。但是，如果您想在 JOIN 查询中使用加密数据并且不担心重复值，则**允许重复**参数可以禁用此保守检查。

## “允许对具有不同名称的列进行 JOIN”参数
<a name="parameter-allowjoin"></a>

在控制台中，您可以在[创建协作](create-collaboration.md)时设置**允许对具有不同名称的列进行 JOIN** 参数，以指定是否支持具有不同名称的列之间的 JOIN 语句。

有关更多信息，请参阅 [列标题名称的标准化](crypto-computing-column-names.md#column-header-names-normalization)。

下表描述了**允许对具有不同名称的列进行 JOIN** 参数的值。


| 参数值 | 说明 | 
| --- | --- | 
| 否  |  不支持联接具有不同名称的 fingerprint 列。JOIN 语句仅在具有相同名称的列上提供准确的结果。  **否**值可提高信息安全性，但要求协作参与者事先就列名达成共识。如果两列在加密为 fingerprint 列时具有不同的名称，并且**允许对具有不同名称的列进行 JOIN** 设置为**否**，则对这些列的 JOIN 语句不会生成任何结果。这是因为它们之间不共享加密后的值。   | 
| 是 |  支持联接具有不同名称的 fingerprint 列。为了提高灵活性，用户可以将此值设置为**是**，这样无论列名如何，都允许对列执行 JOIN 语句。 如果设置为**是**，则 C3R 加密客户端在保护 fingerprint 列时将不会考虑列名。因此，在 C3R 表中可以观察到不同 fingerprint 列的共同值。 例如，如果一行在 `City` 列和 `State` 列中都具有相同的加密 JOIN 值，则可以合理地推断出该值为 `New York`。  | 

使用 `CreateCollaboration` API 操作，对于 `dataEncryptionMetadata` 参数，您可以将 `allowJoinsOnColumnsWithDifferentNames` 的值设置为 `true` 或 `false`。有关 API 操作的更多信息，请参阅 [AWS Clean Rooms API 参考](https://docs.aws.amazon.com/clean-rooms/latest/apireference/Welcome.html)。

默认情况下，fingerprint 列加密受该列的 `targetHeader` 所影响，它在[步骤 4：为表格文件生成加密架构](gen-encryption-schema-csv.md)中设置。因此，同一个 cleartext 值在每个不同的 fingerprint 列中都有不同的加密表示。

在某些情况下，此参数可用于防止推断 cleartext 值。例如，在 fingerprint 列中看到相同的加密值时，可以通过 `City` 和 `State` 来合理地推断该值是 `New York`。但是，使用此参数需要事先进行额外的协调，以便查询中要联接的所有列都具有共享名称。

您可以使用**允许对具有不同名称的列进行 JOIN** 参数来放宽此限制。当参数值设置为 `Yes` 时，无论名称如何，都允许一起使用为 JOIN 加密的任何列。

## “保留 NULL 值”参数
<a name="parameter-preservenulls"></a>

在控制台中，您可以在[创建协作](create-collaboration.md)时设置**保留 NULL 值**参数，以指示该列不存在任何值。

下表描述了**保留 NULL 值**参数的值。


| 参数值 | 说明 | 
| --- | --- | 
| 否 |  NULL 值不会被保留。NULL 值在加密表中不会显示为 NULL。NULL 值在 C3R 表中显示为唯一的随机值。  | 
| 是 | NULL 值会被保留。NULL 值在加密表中显示为 NULL。如果您需要 NULL 值的 SQL 语义，则可以将此值设置为是。因此，无论列是否加密以及允许重复的参数设置如何，NULL 条目在 C3R 表中都会显示为 NULL。 | 

使用 `CreateCollaboration` API 操作，对于 `dataEncryptionMetadata` 参数，您可以将 `preserveNulls` 的值设置为 `true` 或 `false`。有关 API 操作的更多信息，请参阅 [AWS Clean Rooms API 参考](https://docs.aws.amazon.com/clean-rooms/latest/apireference/Welcome.html)。

当协作的**保留 NULL 值**参数设置为**否**时：

1. `cleartext` 列中的 NULL 条目保持不变。

1. 加密 `fingerprint` 列中的 NULL 条目被加密为随机值以隐藏其内容。在 cleartext 中联接带有 NULL 条目的加密列不会生成任何 NULL 条目的任何匹配项。不会进行任何匹配，因为它们各自会收到自己的唯一随机内容。

1. 加密 `sealed` 列中的 NULL 条目已加密。

当协作的**保留 NULL 值**参数的值设置为**是**时，无论列是否加密，所有列中的 NULL 条目都将保持为 NULL。

**保留 NULL 值**参数在数据扩充等情况下非常有用，在这些情况下，您需要共享以 NULL 表示的信息缺失。在 fingerprint 或 HMAC 格式中，如果要进行 JOIN 或 GROUP BY 的列中有 NULL 值，**保留 NULL 值**参数也很有用。

如果**允许重复**和**保留 NULL 值**参数的值设置为**否**，则在 fingerprint 列中包含多个 NULL 条目会产生错误并停止加密。如果任一参数的值设置为**是**，则不会发生此类错误。

# Clean Rooms 加密计算中的可选标志
<a name="crypto-computing-optional-flags"></a>

以下各节描述了在使用 C3R 加密客户端[加密数据](encrypt-data.md)以进行表格文件自定义和测试时可以设置的可选标志。

**Topics**
+ [`--csvInputNULLValue` 标志](#optional-flags-CSVinputNullValue)
+ [`--csvOutputNULLValue` 标志](#optional-flags-CSVoutputNullValue)
+ [`--enableStackTraces` 标志](#optional-flags-enablestacktraces)
+ [`--dryRun` 标志](#optional-flags-dry-run)
+ [`--tempDir` 标志](#optional-flags-working-dir)

## `--csvInputNULLValue` 标志
<a name="optional-flags-CSVinputNullValue"></a>

使用 C3R 加密客户端[加密数据](encrypt-data.md)时，您可以使用 `--csvInputNULLValue` 标志为输入数据中的 NULL 条目指定自定义编码。

下表总结了此标志的用法和参数。


| 用法 | 参数 | 
| --- | --- | 
| 可选。用户可以为输入数据中的 NULL 条目指定自定义编码。 | 输入 CSV 文件中 NULL 值的用户指定编码 | 

NULL 条目是被视为缺少内容的条目，特别是在 SQL 表等更丰富的表格格式的上下文中。尽管由于历史原因 .csv 并不明确支持这种描述，但通常的惯例是将仅包含空格的空条目视为 NULL。因此，这是 C3R 加密客户端的默认行为，可以根据需要对其进行自定义。

## `--csvOutputNULLValue` 标志
<a name="optional-flags-CSVoutputNullValue"></a>

使用 C3R 加密客户端[加密数据](encrypt-data.md)时，您可以使用 `--csvOutputNULLValue` 标志为输出数据中的 NULL 条目指定自定义编码。

下表总结了此标志的用法和参数。


| 用法 | 参数 | 
| --- | --- | 
| 可选。用户可以在生成的输出文件中为 NULL 条目指定自定义编码。 | 输入 CSV 文件中 NULL 值的用户指定编码 | 

NULL 条目是被视为缺少内容的条目，特别是在 SQL 表等更丰富的表格格式的上下文中。尽管由于历史原因 .csv 并不明确支持这种描述，但通常的惯例是将仅包含空格的空条目视为 NULL。因此，这是 C3R 加密客户端的默认行为，可以根据需要对其进行自定义。

## `--enableStackTraces` 标志
<a name="optional-flags-enablestacktraces"></a>

使用 C3R 加密客户端[加密数据](encrypt-data.md)时，可以使用 `--enableStackTraces` 标志提供其他上下文信息，以便在 C3R 遇到错误时报告错误。

AWS 不收集错误。如果遇到错误，请使用堆栈跟踪自行解决错误，或者将堆栈跟踪发送到 支持 寻求帮助。

下表总结了此标志的用法和参数。


| 用法 | 参数 | 
| --- | --- | 
| 可选。用于提供其他上下文信息，以便在 C3R 加密客户端遇到错误时报告错误。 | 无 | 

## `--dryRun` 标志
<a name="optional-flags-dry-run"></a>

[加密](encrypt-data.md)和[解密](decrypt-data.md) C3R 加密客户端命令包括一个可选的 `--dryRun` 标志。该标志采用用户提供的所有参数，并检查它们的有效性和一致性。

您可以使用 `--dryRun` 标志来检查您的架构文件是否有效且与其相应的输入文件一致。

下表总结了此标志的用法和参数。


| 用法 | 参数 | 
| --- | --- | 
| 可选。使 C3R 加密客户端解析参数和检查文件，但不执行加密或解密。 | 无 | 

## `--tempDir` 标志
<a name="optional-flags-working-dir"></a>

您可能需要使用临时目录，因为加密文件有时可能比非加密文件大，具体取决于它们的设置。每个协作还必须对数据集进行加密才能正常工作。

使用 C3R [加密数据](encrypt-data.md)时，可以使用 `--tempDir` 标志来指定在处理输入时可以创建临时文件的位置。

下表总结了此标志的用法和参数。


| 用法 | 参数 | 
| --- | --- | 
| 用户可以指定在处理输入时可以创建临时文件的位置。 | 默认为系统临时目录。 | 

# 使用 Clean Rooms 加密计算进行查询
<a name="crypto-computing-queries"></a>

本主题提供有关编写查询的信息，这些查询使用已使用 Clean Rooms 加密计算加密的数据表。

**Topics**
+ [在 NULL 上分支的查询](#queries-branch-on-null)
+ [将一个源列映射到多个目标列](#queries-mapping)
+ [在 JOIN 和 SELECT 查询中使用相同的数据](#queries-using-same-data)

## 在 NULL 上分支的查询
<a name="queries-branch-on-null"></a>

要在 NULL 语句上设置查询分支，需要使用 `IF x IS NULL THEN 0 ELSE 1` 这样的语法。

查询总是可以在 cleartext 列中的 NULL 语句上分支。

只有当**保留 NULL 值**参数 (`preserveNulls`) 的值设置为 `true` 时，查询才能在 sealed 列和 fingerprint 列中的 NULL 语句上分支。

违反这些限制条件的查询可能会生成不正确的结果。

## 将一个源列映射到多个目标列
<a name="queries-mapping"></a>

将一个源列映射到多个目标列。例如，您可能希望在一列上同时进行 JOIN 和 SELECT。

有关更多信息，请参阅 [在 JOIN 和 SELECT 查询中使用相同的数据](#queries-using-same-data)。

## 在 JOIN 和 SELECT 查询中使用相同的数据
<a name="queries-using-same-data"></a>

如果列中的数据不敏感，则它可以出现在 cleartext 目标列中，这样就可以用于任何目的。

如果列中的数据很敏感，必须同时用于 JOIN 和 SELECT 查询，则应将该源列映射到输出文件中的两个目标列。一列作为 fingerprint 列进行 `type` 加密，一列作为密封列进行 `type` 加密。C3R 加密客户端的交互式架构生成建议标题后缀为 `_fingerprint` 和 `_sealed`。这些标题后缀可以成为快速区分此类列的有用惯例。

# C3R 加密客户端指南
<a name="crypto-computing-guidelines"></a>

C3R 加密客户端是一种工具，它使组织能够将敏感数据整合在一起，从数据分析中获得新的洞察。该工具以加密方式限制了任何一方和在此过程中可以学到 AWS 的内容。尽管这一点至关重要，但以加密方式保护数据的过程可能会在计算和存储资源方面增加大量开销。因此，了解使用每种设置的利弊得失以及如何在保持所需的加密保障的同时优化设置非常重要。本主题重点介绍 C3R 加密客户端和架构中不同设置对性能的影响。

所有 C3R 加密客户端加密设置都提供不同的加密保障。默认情况下，协作级别的设置是最安全的。在创建协作时启用其他功能会削弱隐私保障，从而允许对加密文字进行频率分析等活动。有关如何使用这些设置及其影响的更多信息，请参阅[加密计算 Clean Rooms](crypto-computing.md)。

**Topics**
+ [对列类型的性能影响](#performance-implications)
+ [加密文字大小意外增加疑难解答](#troubleshooting-ciphertext-size)

## 对列类型的性能影响
<a name="performance-implications"></a>

C3R 使用三种列类型：cleartext、fingerprint 和 sealed。每种列类型都提供不同的加密保障，并且具有不同的预期用途。在以下各节中，将讨论列类型的性能影响以及每种设置对性能的影响。

**Topics**
+ [Cleartext 列](#cleartext-columns)
+ [Fingerprint 列](#guidelines-fingerprint-columns)
+ [Sealed 列](#guidelines-sealed-columns)

### Cleartext 列
<a name="cleartext-columns"></a>

Cleartext 列不会改变其原始格式，也不会以任何方式进行加密处理。此列类型无法配置，也不会影响存储或计算性能。

### Fingerprint 列
<a name="guidelines-fingerprint-columns"></a>

Fingerprint 列旨在用于联接多个表中的数据。为此，生成的加密文字大小必须始终相同。但是，这些列受协作级别设置的影响。Fingerprint 列可能会对输出文件大小产生不同程度的影响，具体取决于输入中包含的 cleartext。

**Topics**
+ [fingerprint 列的基本开销](#fingerprint-columns-base-overhead)
+ [fingerprint 列的协作设置](#fingerprint-columns-collab-settings)
+ [fingerprint 列的示例数据](#collab-set-sample-data)
+ [fingerprint 列疑难解答](#fingerprint-columns-troubleshooting)

#### fingerprint 列的基本开销
<a name="fingerprint-columns-base-overhead"></a>

fingerprint 列有基本开销。这种开销是恒定的，与 cleartext 字节的大小无关。

fingerprint 列中的数据通过 HMAC 散列消息认证码函数进行加密处理，该函数将数据转换为 32 字节的消息认证码 (MAC)。然后通过 base64 编码器对这些数据进行处理，使字节大小增加约 33%。它前面有一个 8 字节的 C3R 标识，用于指定数据所属的列类型以及生成数据的客户端版本。最终结果为 52 字节。然后将此结果乘以行数得出总基本开销（如果 `preserveNulls` 设置为 true，则使用非 `null` 值总数）。

下图显示了如何操作 * `BASE_OVERHEAD = ` ** `C3R_DESIGNATION + ` ** `(MAC * 1.33)` *

![\[fingerprint 列的 52 字节基本开销。\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/images/base-overhead-fingerprint.PNG)


fingerprint 列中的输出加密文字将始终为 52 字节。如果输入 cleartext 数据的平均值超过 52 字节（例如，完整的街道地址），则存储空间可能会显著减少。如果输入 cleartext 数据的平均值小于 52 字节（例如，客户年龄），则存储空间可能会显著增加。

#### fingerprint 列的协作设置
<a name="fingerprint-columns-collab-settings"></a>

##### `preserveNulls` 设置
<a name="collab-set-preserve-nulls"></a>

当协作级别设置 `preserveNulls` 为 `false`（默认值）时，每个 `null` 值都将替换为一个唯一的随机 32 字节，并被当作非 `null` 处理。结果是，现在每个 `null` 值都是 52 字节。与此设置为 `true` 且 `null` 值作为 `null` 传递时相比，对于包含非常稀疏的数据的表，这可能会增加大量存储需求。

如果您不需要此设置的隐私保障，并且希望在数据集中保留 `null` 值，请在创建协作时启用 `preserveNulls` 设置。创建协作后将无法更改 `preserveNulls` 设置。

#### fingerprint 列的示例数据
<a name="collab-set-sample-data"></a>

以下是带有要重现设置的 fingerprint 列的输入和输出数据的示例集。其他协作级别的设置（例如 `allowCleartext` 和 `allowDuplicates`）不会影响结果，如果尝试在本地重现，则可以设置为 `true` 或 `false`。

**共享密钥示例**：`wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`

**协作 ID 示例**：`a1b2c3d4-5678-90ab-cdef-EXAMPLE11111`

**allowJoinsOnColumnsWithDifferentNames**：`True` 此设置不会影响性能或存储要求。但是，在重现下表中显示的值时，此设置使列名的选择变得无关紧要。


**示例 1**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | TRUE | 
| Output | null | 
| 确定性 | Yes | 
| 输入字节 | 0 | 
| 输出字节 | 0 | 


**示例 2**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | FALSE | 
| Output | 01:hmac:3lkFjthvV3IUu6mMvFc1a\$1XAHwgw/ElmOq4p3Yg25kk= | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 52 | 


**示例 3**  

|  |  | 
| --- |--- |
| Input | empty string | 
| preserveNulls | - | 
| Output | 01:hmac:oKTgi3Gba\$1eUb3JteSz2EMgXUkF1WgM77UP0Ydw5kPQ= | 
| 确定性 | Yes | 
| 输入字节 | 0 | 
| 输出字节 | 52 | 


**示例 4**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyz | 
| preserveNulls | - | 
| Output | 01:hmac:kU/IqwG7FMmzzshr0B9scomE0UJUEE7j9keTctplGww= | 
| 确定性 | Yes | 
| 输入字节 | 26 | 
| 输出字节 | 52 | 


**示例 5**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 | 
| preserveNulls | - | 
| Output | 01:hmac:ks3htnQbw2vdhCRFF6JNzW5LMndJaHG57uvE26mBtSs= | 
| 确定性 | Yes | 
| 输入字节 | 62 | 
| 输出字节 | 52 | 

#### fingerprint 列疑难解答
<a name="fingerprint-columns-troubleshooting"></a>

**为什么我的 fingerprint 列中的加密文字比进入它的 cleartext 大几倍？**

fingerprint 列中的加密文字的长度始终为 52 字节。如果您的输入数据很小（例如，客户的年龄），则其大小将显著增加。如果将 `preserveNulls` 设置设置为 `false`，也可能发生这种情况。

**为什么我的 fingerprint 列中的加密文字比进入它的 cleartext 小几倍？**

fingerprint 列中的加密文字的长度始终为 52 字节。如果您的输入数据很大（例如，客户的完整街道地址），则其大小将显著减小。

**我怎么知道我是否需要 `preserveNulls` 提供的加密保障？**

遗憾的是，答案是“看情况”。至少，应查看 [加密计算参数](crypto-computing-parameters.md) 了解 `preserveNulls` 设置如何保护您的数据。但是，我们建议您参考组织的数据处理要求以及适用于相应协作的任何合同。

**为什么我必须承担 base64 的开销？**

为了与 CSV 等表格文件格式兼容，必须进行 base64 编码。尽管某些文件格式（例如 Parquet）可能支持数据的二进制表示，但重要的是，协作中的所有参与者都必须以相同的方式表示数据，以确保查询结果正确。

### Sealed 列
<a name="guidelines-sealed-columns"></a>

Sealed 列用于在协作成员之间传输数据。这些列中的加密文字是不确定的，并且会根据列的配置方式对性能和存储产生重大影响。这些列可以单独配置，通常对 C3R 加密客户端的性能和由此产生的输出文件大小影响最大。

**Topics**
+ [sealed 列的基本开销](#sealed-columns-base-overhead)
+ [sealed 列的协作设置](#sealed-columns-collab-settings)
+ [架构设置 sealed 列：填充类型](#sealed-collab-pad-type)
+ [sealed 列的示例数据](#sealed-collab-sample-data)
+ [sealed 列疑难解答](#troubleshooting-sealed-columns)

#### sealed 列的基本开销
<a name="sealed-columns-base-overhead"></a>

sealed 列有基本开销。此开销是恒定的，是 cleartext 和填充（如有）字节大小之外的开销。

在进行任何加密之前，在 sealed 列中的数据前面加上一个 1 字节的字符，表示所包含的数据类型。如果选择了填充，则会对数据进行填充并追加 2 个字节，说明填充大小。添加这些字节后，使用 AES-GCM 对数据进行加密处理，并以 IV（12 字节）、nonce（32 字节）和 Auth Tag（16 字节）进行存储。然后通过 base64 编码器对这些数据进行处理，使字节大小增加约 33%。数据前面有一个 7 字节的 C3R 标识，用于指定数据属于哪种类型的列以及用于生成数据的客户端版本。结果是 91 字节的最终基本开销。然后将此结果乘以行数得出总基本开销（如果 `preserveNulls` 设置为 true，则使用非 null 值总数）。

下图显示了如何操作 * `BASE_OVERHEAD = C3R_DESIGNATION + ((NONCE + IV + DATA_TYPE + PAD_SIZE + AUTH_TAG) * 1.33)` *

![\[sealed 列的 91 字节基本开销。\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/userguide/images/base-overhead-sealed.PNG)


#### sealed 列的协作设置
<a name="sealed-columns-collab-settings"></a>

##### `preserveNulls` 设置
<a name="sealed-collab-set-preserve-nulls"></a>

当协作级别设置 `preserveNulls` 为 `false`（默认值）时，每个 `null` 值都将是唯一的随机 32 字节，并被当作非 `null` 处理。结果是，现在每个 `null` 值都是 91 字节（如果填充，则更多）。与此设置为 `true` 且 `null` 值作为 `null` 传递时相比，对于包含非常稀疏的数据的表，这可能会增加大量存储需求。

如果您不需要此设置的隐私保障，并且希望在数据集中保留 `null` 值，请在创建协作时启用 `preserveNulls` 设置。创建协作后将无法更改 `preserveNulls` 设置。

#### 架构设置 sealed 列：填充类型
<a name="sealed-collab-pad-type"></a>

**Topics**
+ [`none` 的填充类型](#pad-type-none)
+ [`fixed` 的填充类型](#pad-type-fixed)
+ [`max` 的填充类型](#pad-type-max)

##### `none` 的填充类型
<a name="pad-type-none"></a>

选择 `none` 的填充类型不会向 cleartext 增加任何填充，也不会在前面描述的基本开销之外增加额外的开销。没有填充会产生最节省空间的输出大小。但是，它不提供与 `fixed` 和 `max` 填充类型相同的隐私保障。这是因为底层 cleartext 的大小可以从加密文字的大小中分辨出来。

##### `fixed` 的填充类型
<a name="pad-type-fixed"></a>

选择 `fixed` 的填充类型是一种隐私保护措施，用于隐藏列中包含的数据的长度。这是通过在加密之前将所有 `pad_length` 填充到提供的 cleartext 来完成的。任何超过该大小的数据都会导致 C3R 加密客户端失败。

假设填充是在加密之前添加到 cleartext 的，因此 AES-GCM 具有 cleartext 到加密文字字节的 1:1 映射。base64 编码将增加 33%。填充的额外存储开销可以通过从 `pad_length` 的值中减去 cleartext 的平均长度，然后乘以 1.33 来计算。结果就是每条记录的平均填充开销。然后将此结果乘以行数得出总填充开销（如果 `preserveNulls` 设置为 `true`，则使用非 `null` 值总数）。

 `PADDING_OVERHEAD = (PAD_LENGTH - AVG_CLEARTEXT_LENGTH) * 1.33 * ROW_COUNT`

我们建议您选择包含列中最大值的最小 `pad_length`。例如，如果最大值为 50 字节，则 `pad_length` 为 50 就足够了。大于该值的值只会增加额外的存储开销。

固定填充不会增加任何显著的计算开销。

##### `max` 的填充类型
<a name="pad-type-max"></a>

选择 `max` 的填充类型是一种隐私保护措施，用于隐藏列中包含的数据的长度。这是通过将所有 cleartext 填充到列中的最大值再加上加密之前的额外 `pad_length` 来完成的。通常，`max` 填充提供的保障与单个数据集的 `fixed` 填充相同，同时允许不知道列中的最大 cleartext 值。但是，`max` 填充可能无法提供与跨更新的 `fixed` 填充相同的隐私保障，因为各个数据集中的最大值可能有所不同。

我们建议您在使用 `max` 填充时，额外选择 0 的 `pad_length`。此长度将所有值填充到与列中最大值的大小相同。大于该值的值只会增加额外的存储开销。

如果已知给定列的最大 cleartext 值，我们建议您改用 `fixed` 填充类型。使用 `fixed` 填充可在更新的数据集之间实现一致性。使用 `max` 填充会使每个数据子集填充到该子集中的最大值。

#### sealed 列的示例数据
<a name="sealed-collab-sample-data"></a>

以下是带有要重现设置的 sealed 列的输入和输出数据的示例集。其他协作级别的设置（例如 `allowCleartext`、`allowJoinsOnColumnsWithDifferentNames` 和 `allowDuplicates`）不会影响结果，如果尝试在本地重现，则可以设置为 `true` 或 `false`。尽管这些是要重现的基本设置，但 sealed 列是不确定的，值每次都会更改。目的是显示输入字节与输出字节的对比。示例 `pad_length` 值是故意选择的。它们表明，使用推荐的最低 `pad_length` 设置或需要额外的填充时， `fixed` 填充产生的值与 `max` 填充相同。

**共享密钥示例**：`wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`

**协作 ID 示例**：`a1b2c3d4-5678-90ab-cdef-EXAMPLE11111`

**Topics**
+ [`none` 的填充类型](#sealed-pad-type-none)
+ [`fixed` 的填充类型（示例 1）](#sealed-pad-type-fixed)
+ [`fixed` 的填充类型（示例 2）](#sealed-pad-type-fixed-2)
+ [`max` 的填充类型（示例 1）](#sealed-pad-type-max)
+ [`max` 的填充类型（示例 2）](#sealed-pad-type-max-2)

##### `none` 的填充类型
<a name="sealed-pad-type-none"></a>


**示例 1**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | TRUE | 
| Output | null | 
| 确定性 | Yes | 
| 输入字节 | 0 | 
| 输出字节 | 0 | 


**示例 2**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | FALSE | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfssGSPbNIJfG3iXmu6cbCUrizuV | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 91 | 


**示例 3**  

|  |  | 
| --- |--- |
| Input | empty string | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfstGSPEM6qR8DWC2PB2GMlX41YK | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 91 | 


**示例 4**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyz | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6pkx9sGL5VLDQeHzh6DmPpyWNuI= | 
| 确定性 | No | 
| 输入字节 | 26 | 
| 输出字节 | 127 | 


**示例 5**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6plwtH/8tRFnn2rF91bcB9G4\$1n8GiRfJNmqdP4/QOQ3cXb/pbvPcnnohrHIGSX54ua\$11/JfcVjc= | 
| 确定性 | No | 
| 输入字节 | 62 | 
| 输出字节 | 175 | 

##### `fixed` 的填充类型（示例 1）
<a name="sealed-pad-type-fixed"></a>

在此示例中，`pad_length` 为 62，最大输入为 62 字节。


**示例 1**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | TRUE | 
| Output | null | 
| 确定性 | Yes | 
| 输入字节 | 0 | 
| 输出字节 | 0 | 


**示例 2**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | FALSE | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfssGSNWfMRp7nSb7SMX2s3JKLOhK1\$17r75Tk\$1Mx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcoNpATs0GzbnLkor4L\$1/aSuA= | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 175 | 


**示例 3**  

|  |  | 
| --- |--- |
| Input | empty string | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfstGSNWfMRp7nSb7SMX2s3JKLOhK1\$17r75Tk\$1Mx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcoLB53l07VZpA6OwkuXu29CA= | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 175 | 


**示例 4**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyz | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6pkx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcutBAcO\$1Mb9tuU2KIHH31AWg= | 
| 确定性 | No | 
| 输入字节 | 26 | 
| 输出字节 | 175 | 


**示例 5**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6plwtH/8tRFnn2rF91bcB9G4\$1n8GiRfJNmqdP4/QOQ3cXb/pbvPcnnohrHIGSX54ua\$11/JfcVjc= | 
| 确定性 | No | 
| 输入字节 | 62 | 
| 输出字节 | 175 | 

##### `fixed` 的填充类型（示例 2）
<a name="sealed-pad-type-fixed-2"></a>

在此示例中，`pad_length` 为 162，最大输入为 62 字节。


**示例 1**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | TRUE | 
| Output | null | 
| 确定性 | Yes | 
| 输入字节 | 0 | 
| 输出字节 | 0 | 


**示例 2**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | FALSE | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfssGSNWfMRp7nSb7SMX2s3JKLOhK1\$17r75Tk\$1Mx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcnkB0xbLWD7zNdAqQGR0rXoSESdW0I0vpNoGcBfv4cJbG0A3h1DvtkSSVc2B80OOGppzdDqhrUVN5wFNyn8vgfPMqDaeJk5bn\$18o4WtG/ClipNcjDXvXVtK4vfCohcCA6uwrmwv/xAySX\$1xcntotL703aBTBb | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 307 | 


**示例 3**  

|  |  | 
| --- |--- |
| Input | empty string | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfstGSNWfMRp7nSb7SMX2s3JKLOhK1\$17r75Tk\$1Mx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcnkB0xbLWD7zNdAqQGR0rXoSESdW0I0vpNoGcBfv4cJbG0A3h1DvtkSSVc2B80OOGppzdDqhrUVN5wFNyn8vgfPMqDaeJk5bn\$18o4WtG/ClipNcjDXvXVtK4vfCohcCA6uwrmwv84lVaT9Yd\$16oQx65/\$1gdVT | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 307 | 


**示例 4**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyz | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6pkx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcnkB0xbLWD7zNdAqQGR0rXoSESdW0I0vpNoGcBfv4cJbG0A3h1DvtkSSVc2B80OOGppzdDqhrUVN5wFNyn8vgfPMqDaeJk5bn\$18o4WtG/ClipNcjDXvXVtK4vfCohcCA6uwrmwtX5Hnl\$1WyfO6ks3QMaRDGSf | 
| 确定性 | No | 
| 输入字节 | 26 | 
| 输出字节 | 307 | 


**示例 5**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6plwtH/8tRFnn2rF91bcB9G4\$1n8GiRfJNmqdP4/QOQ3cXb/pbvPcnkB0xbLWD7zNdAqQGR0rXoSESdW0I0vpNoGcBfv4cJbG0A3h1DvtkSSVc2B80OOGppzdDqhrUVN5wFNyn8vgfPMqDaeJk5bn\$18o4WtG/ClipNcjDXvXVtK4vfCohcCA6uwrmwjkJXQZOgPdeFX9Yr/8alV5i | 
| 确定性 | No | 
| 输入字节 | 62 | 
| 输出字节 | 307 | 

##### `max` 的填充类型（示例 1）
<a name="sealed-pad-type-max"></a>

在此示例中，`pad_length` 为 0，最大输入为 62 字节。


**示例 1**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | TRUE | 
| Output | null | 
| 确定性 | Yes | 
| 输入字节 | 0 | 
| 输出字节 | 0 | 


**示例 2**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | FALSE | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfssGSNWfMRp7nSb7SMX2s3JKLOhK1\$17r75Tk\$1Mx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcoNpATs0GzbnLkor4L\$1/aSuA= | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 175 | 


**示例 3**  

|  |  | 
| --- |--- |
| Input | empty string | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfstGSNWfMRp7nSb7SMX2s3JKLOhK1\$17r75Tk\$1Mx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcoLB53l07VZpA6OwkuXu29CA= | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 175 | 


**示例 4**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyz | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6pkx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcutBAcO\$1Mb9tuU2KIHH31AWg= | 
| 确定性 | No | 
| 输入字节 | 26 | 
| 输出字节 | 175 | 


**示例 5**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6plwtH/8tRFnn2rF91bcB9G4\$1n8GiRfJNmqdP4/QOQ3cXb/pbvPcnnohrHIGSX54ua\$11/JfcVjc= | 
| 确定性 | No | 
| 输入字节 | 62 | 
| 输出字节 | 175 | 

##### `max` 的填充类型（示例 2）
<a name="sealed-pad-type-max-2"></a>

在此示例中，`pad_length` 为 100，最大输入为 62 字节。


**示例 1**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | TRUE | 
| Output | null | 
| 确定性 | Yes | 
| 输入字节 | 0 | 
| 输出字节 | 0 | 


**示例 2**  

|  |  | 
| --- |--- |
| Input | null | 
| preserveNulls | FALSE | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfssGSNWfMRp7nSb7SMX2s3JKLOhK1\$17r75Tk\$1Mx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcnkB0xbLWD7zNdAqQGR0rXoSESdW0I0vpNoGcBfv4cJbG0A3h1DvtkSSVc2B80OOGppzdDqhrUVN5wFNyn8vgfPMqDaeJk5bn\$18o4WtG/ClipNcjDXvXVtK4vfCohcCA6uwrmwv/xAySX\$1xcntotL703aBTBb | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 307 | 


**示例 3**  

|  |  | 
| --- |--- |
| Input | empty string | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfstGSNWfMRp7nSb7SMX2s3JKLOhK1\$17r75Tk\$1Mx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcnkB0xbLWD7zNdAqQGR0rXoSESdW0I0vpNoGcBfv4cJbG0A3h1DvtkSSVc2B80OOGppzdDqhrUVN5wFNyn8vgfPMqDaeJk5bn\$18o4WtG/ClipNcjDXvXVtK4vfCohcCA6uwrmwv84lVaT9Yd\$16oQx65/\$1gdVT | 
| 确定性 | No | 
| 输入字节 | 0 | 
| 输出字节 | 307 | 


**示例 4**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyz | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6pkx9jy48Fcg1yOPvBqRSZ7oqy1V3UKfYTLEZb/hCz7oaIneVsrcnkB0xbLWD7zNdAqQGR0rXoSESdW0I0vpNoGcBfv4cJbG0A3h1DvtkSSVc2B80OOGppzdDqhrUVN5wFNyn8vgfPMqDaeJk5bn\$18o4WtG/ClipNcjDXvXVtK4vfCohcCA6uwrmwtX5Hnl\$1WyfO6ks3QMaRDGSf | 
| 确定性 | No | 
| 输入字节 | 26 | 
| 输出字节 | 307 | 


**示例 5**  

|  |  | 
| --- |--- |
| Input | abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 | 
| preserveNulls | - | 
| Output | 01:enc:bm9uY2UwMTIzNDU2Nzg5MG5vbmNlMDEyMzQ1Njc4OTBqfRYZ98t5KU6aWfsteEE1GKEPiRzyh0h7t6OmWMLTWCvO2ckr6plwtH/8tRFnn2rF91bcB9G4\$1n8GiRfJNmqdP4/QOQ3cXb/pbvPcnkB0xbLWD7zNdAqQGR0rXoSESdW0I0vpNoGcBfv4cJbG0A3h1DvtkSSVc2B80OOGppzdDqhrUVN5wFNyn8vgfPMqDaeJk5bn\$18o4WtG/ClipNcjDXvXVtK4vfCohcCA6uwrmwjkJXQZOgPdeFX9Yr/8alV5i | 
| 确定性 | No | 
| 输入字节 | 62 | 
| 输出字节 | 307 | 

#### sealed 列疑难解答
<a name="troubleshooting-sealed-columns"></a>

**为什么我的 sealed 列中的加密文字比进入它的 cleartext 大几倍？**

这取决于多个因素。首先，Cleartext 列中的加密文字的长度始终至少为 91 字节。如果您的输入数据很小（例如，客户的年龄），则其大小将显著增加。其次，如果 `preserveNulls` 设置为 `false`，并且您的输入数据包含很多 `null` 值，则每个 `null` 值都将变成 91 字节的加密文字。最后，如果您使用填充，则根据定义，在加密 cleartext 数据之前会将字节添加到该数据中。

**我的 sealed 列中的大部分数据都非常小，我需要使用填充。我可以删除大值并单独处理它们以节省空间吗？**

我们不建议删除大值并单独处理。这样做会改变 C3R 加密客户端提供的隐私保证。作为威胁模型，假设观察者可以看到两个加密的数据集。如果观察者发现一个数据子集的列填充明显大于或小于另一个子集，则他们可以推断每个子集中数据的大小。例如，假设 `fullName` 列在一个文件中填充到总共 40 字节，而在另一个文件中填充到 800 字节。观察者可能会认为，其中一个数据集包含了世界上最长的名字（747 字节）。

**使用 `max` 填充类型时，我需要提供额外的填充吗？**

不需要。使用 `max` 填充时，我们建议将 `pad_length`（也称为列中最大值*之外*的额外填充）设置为 0。

**我能否在使用 `fixed` 填充时选择大的 `pad_length` 来避免担心最大的值是否合适？**

能，但是大的填充长度效率低下，并且占用的存储空间超出了必要的范围。我们建议您查看最大值有多大，并将 `pad_length` 设置为该值。

**我怎么知道我是否需要 `preserveNulls` 提供的加密保障？**

遗憾的是，答案是“看情况”。至少，应查看 [加密计算 Clean Rooms](crypto-computing.md) 了解 `preserveNulls` 设置如何保护您的数据。但是，我们建议您参考组织的数据处理要求以及适用于相应协作的任何合同。

**为什么我必须承担 base64 的开销？**

为了与 CSV 等表格文件格式兼容，必须进行 base64 编码。尽管某些文件格式（例如 Parquet）可能支持数据的二进制表示，但重要的是，协作中的所有参与者都必须以相同的方式表示数据，以确保查询结果正确。

## 加密文字大小意外增加疑难解答
<a name="troubleshooting-ciphertext-size"></a>

假设您加密了数据，结果数据的大小出人意料地大。以下步骤可以帮助您确定大小增加的位置以及可以采取的措施（如果有）。

### 确定大小增加的位置
<a name="where-size-increase-occurred"></a>

在排查加密数据明显大于 cleartext 数据的原因之前，必须先确定大小的增加位置。可以放心地忽略 Cleartext 列，因为它们没有变化。查看其余的 fingerprint 和 sealed 列，然后选择一个看起来很重要的列。

### 确定大小增加的原因
<a name="why-size-increase-occurred"></a>

fingerprint 列或 sealed 列可能会导致大小增加。

**Topics**
+ [大小增加是否来自 fingerprint 列？](#size-increase-from-fingerprint)
+ [大小增加是否来自 sealed 列？](#size-increase-from-sealed)

#### 大小增加是否来自 fingerprint 列？
<a name="size-increase-from-fingerprint"></a>

如果对存储增加贡献最大的列是 fingerprint 列，则可能是因为 cleartext 数据很小（例如，客户年龄）。生成的每个 fingerprint 加密文字的长度为 52 字节。不幸的是，在这个问题上无能为 column-by-column力。有关更多信息，请参阅 [fingerprint 列的基本开销](#fingerprint-columns-base-overhead) 了解有关此列的详细信息，包括它如何影响存储要求。

导致 fingerprint 列中大小增加的另一个可能原因是协作设置 `preserveNulls`。如果禁用了 `preserveNulls` 的协作设置（默认设置），则 fingerprint 列中的所有 `null` 值都将变为 52 字节的加密文字。目前的协作对此无能为力。`preserveNulls` 设置是在创建协作时设置的，所有协作者必须使用相同的设置以确保查询结果正确。有关 `preserveNulls` 设置以及启用它会如何影响数据隐私保障的更多信息，请参阅 [加密计算 Clean Rooms](crypto-computing.md)。

#### 大小增加是否来自 sealed 列？
<a name="size-increase-from-sealed"></a>

如果对存储增加贡献最大的列是 sealed 列，那么有一些细节可能会导致大小增加。

如果 cleartext 数据很小（例如，客户年龄），则生成的每个 sealed 加密文字的长度至少为 91 字节。遗憾的是，我们对这个问题无能为力。有关更多信息，请参阅 [sealed 列的基本开销](#sealed-columns-base-overhead) 了解有关此列的详细信息，包括它如何影响存储要求。

sealed 列存储增加的第二个主要原因是填充。填充会在加密 cleartext 之前向其添加额外的字节，以隐藏数据集中各个值的大小。我们建议您将数据集的填充设置为可能的最小值。至少必须将 `fixed` 填充的 `pad_length` 设置为包含列中可能的最大值。任何高于此值的设置都不会增加额外的隐私保障。例如，如果您知道列中可能的最大值可能为 50 字节，我们建议您将 `pad_length` 设置为 50 字节。但是，如果 sealed 列使用 `max` 填充，我们建议您将 `pad_length` 设置为 0 字节。这是因为 `max` 填充是指列中最大值之外的*额外*填充。

导致 sealed 列中大小增加的最后一个可能原因是协作设置 `preserveNulls`。如果禁用了 `preserveNulls` 的协作设置（默认设置），则 sealed 列中的所有 `null` 值都将变为 91 字节的加密文字。目前的协作对此无能为力。`preserveNulls` 设置是在创建协作时设置的，所有协作者必须使用相同的设置以确保查询结果正确。有关此设置以及启用它会如何影响数据隐私保障的更多信息，请参阅 [加密计算 Clean Rooms](crypto-computing.md)。