在 Snowflake 中使用合成数据¶
此预览版介绍了一种用于生成合成数据的新存储过程,GENERATE_SYNTHETIC_DATA。
概述¶
Snowflake 可以从源表生成 合成数据,生成一个与源表具有相同列数但包含统计类似的人工数据的表。您可以使用合成数据来共享或测试过于敏感、机密或以其他方式限制与他人共享的数据。合成数据集具有与源数据集相同的特征,例如列的名称、编号和数据类型,以及相同或更少的行数。您可以使用合成数据来测试和验证 Snowflake 中的工作负载,特别是当原始数据为敏感数据且不应受到未经授权的用户访问时。
优势¶
- 统计一致性:
表示原始数据集统计特性的合成数据集,可以帮助数据工程师了解真实数据集的统计特性。随后,数据工程师可以测试和验证基于真实数据集的解决方案。
- 生产验证:
与生产数据集相似的合成数据集让生产工程师能够测试和验证其生产环境。从而让生产环境更加强大。
关于合成数据算法¶
Snowflake 使用算法生成与原始数据集相似的合成数据。该算法使用原始数据集生成与原始数据集具有相同统计特性的合成数据。捕获分布后,合成数据将在统计上具有类似于原始数据的特征,但与原始数据中的任何行之间没有直接的引用或链接。
生成合成数据¶
调用 GENERATE_SYNTHETIC_DATA,从一个或多个表生成合成数据。Snowflake 创建合成数据表,并将所有权授予调用存储过程的角色。输出表的列数与输入表相同,列名和数据类型也相同。输出通常具有相同的行数,除非您启用 隐私筛选器 或输入表具有 NULL 值,在这种情况下,输出表可能具有更少的行。
生成的数据值¶
Snowflake 根据源数据类型为非联接键列生成合成数据:
统计数据: 数字、布尔、日期、时间或时间戳类型的数据。生成的数据是相同的类型,与源数据具有相同的值。
分类字符串: 具有 少量 唯一值‡ 的字符串列。生成的数据使用源数据中的实际值。
非分类字符串: 具有 许多 唯一值‡ 的字符串列。已在输出中编辑,除非您使用 GENERATE_SYNTHETIC_DATA 中的
replace
选项指定输出格式。
您可以为 GENERATE_SYNTHETIC_DATA 提供 categorical
值,明确将非联接键字符串列指定为分类或非分类。联接键列必须是非分类字符串或统计数据。
每个表中生成的数据将保持原始表中存在的近似分布和相关性。
指定为联接键的列可以是任何数据类型,并且将产生相同类型的合成数据和一致的人为值。
‡ 少量唯一值 意味着唯一值的数量少于行数的一半。大量唯一值 意味着唯一值的数量超过行数的一半。
在合成数据中保持联接键一致性¶
如果您计划对合成数据运行联接查询,请将您将联接的每一列指定为 联接键。您可以在 GENERATE_SYNTHETIC_DATA 中指定 join_key
值,将任何数字列、布尔列或非分类列指定为联接键。在单次运行中,对于所有表中的所有联接键,源数据中的相同值在输出数据中生成一致的合成值。这样您就能够运行联接查询,并获得与对源数据运行相同查询时相似的结果。
保持表之间的联接一致性,请确保每个表中的相同联接键列具有相同的实参。也就是说,如果您期望 cust_id
跨表联接,请在每个数据集对象的 columns
描述中提供相同的一组实参和值:
'datasets':[
{
'input_table': 'd.s.orders',
'output_table': 'd.s.orders_synth',
'columns': {'cust_id': {'join_key': True, 'replace': 'uuid'}, ...}
},
{
'input_table': 'd.s.customers',
'output_table': 'd.s.customers_synth',
'columns' : {'cust_id': {'join_key': True, 'replace':'uuid'}, ...}
}
]
如果您在 GENERATE_SYNTHETIC_DATA 中为 consistency_secret
提供 对称字符串密钥,则联接键值将在表和多个运行之间保持一致。如果您未指定密钥,则联接键值将在单次运行的所有表中保持一致,但在多次运行中则不一致。仅字符串列支持多次运行一致性。
示例:单次运行联接键一致性
CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
'datasets':[
{
'input_table': 'CLINICAL_DB.PUBLIC.PATIENTS1',
'output_table': 'MY_DB.PUBLIC.PATIENTS1',
'columns': { 'patient_id': {'join_key': TRUE}, 'age':{'join_key': TRUE}}
},
{
'input_table': 'CLINICAL_DB.PUBLIC.PATIENTS2',
'output_table': 'MY_DB.PUBLIC.PATIENTS2',
'columns': { 'patient_id': {'join_key': TRUE}, 'age':{'join_key': TRUE}}
}
],
'replace_output_tables': TRUE
});
示例:多次运行联接键一致性
-- Generate consistent join keys across multiple runs by
-- providing a symmetric key secret.
CREATE OR REPLACE SECRET my_db.public.my_consistency_secret
TYPE=SYMMETRIC_KEY
ALGORITHM=GENERIC;
CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
'datasets':[
{
'input_table': 'CLINICAL_DB.PUBLIC.BASE_TABLE',
'output_table': 'MY_DB.PUBLIC.PATIENTS1',
'columns': { 'patient_id': {'join_key': TRUE}}
}
],
'consistency_secret': SYSTEM$REFERENCE('SECRET', 'MY_CONSISTENCY_SECRET', 'SESSION', 'READ')::STRING,
'replace_output_tables': TRUE
});
CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({
'datasets':[
{
'input_table': 'CLINICAL_DB.PUBLIC.SECOND_TABLE',
'output_table': 'MY_DB.PUBLIC.PATIENTS2',
'columns': { 'patient_id': {'join_key': TRUE}}
}
],
'consistency_secret': SYSTEM$REFERENCE('SECRET', 'MY_CONSISTENCY_SECRET', 'SESSION', 'READ')::STRING,
'replace_output_tables': TRUE
});
增强隐私保护¶
调用 GENERATE_SYNTHETIC_DATA 存储过程时,您可以选择性地设置 'similarity_filter': True
配置选项,以对输出表应用隐私过滤器。隐私过滤器会从输出表中删除与输入数据集过于相似的行。隐私阈值使用最近邻距离比 (NNDR) 和到最近记录的距离 (DCR) 值来确定是否应从输出表中删除一行。
要求¶
输入表格要求¶
支持表和视图作为源数据。您可以在每个过程调用中指定最多五个输入表。
要生成合成数据,每个 输入表或视图必须满足以下要求:
至少 20 行不同的内容
最多 100 列
最多 230 万行
支持 以下输入表类型:
常规、临时、动态和瞬态表
常规、物化、安全和安全物化视图
不 支持以下输入表类型:
外部、Apache Iceberg™ 和混合表
流
支持以下列类型。不支持数据类型的列针对列中的所有值返回 NULL。
所有数字类型(NUMBER、DECIMAL、FLOAT、INTEGER 等)
BOOLEAN
所有日期和时间类型(DATE、DATETIME、TIME、TIMESTAMP 等),除了 TIMESTAMP_TZ
STRING、VARCHAR、CHAR、CHARACTER、TEXT
如果 STRING 列中的值超过一半是唯一值,Snowflake 会因为隐私问题在输出表中用编辑后的值替换该值。
访问控制要求¶
要生成合成数据,您必须使用具有以下各项权限的角色:
要用于查询的仓库的 USAGE。
要生成合成数据的输入表的 SELECT。
包含输入表的数据库和架构以及包含输出表的数据库的 USAGE。
包含输出表的架构的 CREATE TABLE。
输出表的 OWNERSHIP。最简单的方法是将 OWNERSHIP 授予生成输出表的架构。(然而,如果有人在此架构上应用了 FUTURE GRANT,表的所有权将被静默覆盖,也就是说,
GRANT OWNERSHIP ON FUTURE TABLES IN SCHEMA db.my_schema TO ROLE some_role
会自动将 OWNERSHIP 授予在架构my_schema
中创建的任何新表的some_role
。)
所有用户都可以访问 SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA 存储过程。访问是通过使用 SNOWFLAKE.CORE_VIEWER 数据库角色实现的,其被授予 PUBLIC 角色。
其他要求¶
您必须在 Snowflake 账户中 接受 Anaconda 条款和条件 才能启用此功能。
建议¶
使用中型 Snowpark 优化型仓库。
GENERATE_SYNTHETIC_DATA
运行时,请勿在该仓库中运行其他查询。
示例:来自多个表的合成数据¶
此示例使用 Snowflake 示例数据数据库 SNOWFLAKE_SAMPLE_DATA。如果在账户中看不到该数据库,可以使用以下命令复制:
USE ROLE ACCOUNTADMIN;
CREATE or REPLACE DATABASE SNOWFLAKE_SAMPLE_DATA from share SFC_SAMPLES.SAMPLE_DATA;
按照以下步骤从多个输入表生成合成数据:
为
data_engineer
角色创建并配置访问控制,以允许他们创建所有必要的对象:USE ROLE ACCOUNTADMIN; CREATE OR REPLACE ROLE data_engineer; CREATE OR REPLACE DATABASE syndata_db; CREATE OR REPLACE WAREHOUSE syndata_wh; GRANT OWNERSHIP ON DATABASE syndata_db TO ROLE data_engineer; GRANT USAGE ON WAREHOUSE syndata_wh TO ROLE data_engineer; GRANT ROLE data_engineer TO USER jsmith; -- Or whoever you want to run this example. Or skip this line to run it yourself.
从 Snowflake 示例数据数据库创建两个视图:
- Sign in as user with data_engineer role. Then... CREATE SCHEMA syndata_db.sch; CREATE OR REPLACE VIEW syndata_db.sch.TPC_ORDERS_5K as ( SELECT * from SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.ORDERS LIMIT 5000 ); CREATE OR REPLACE VIEW syndata_db.sch.TPC_CUSTOMERS_5K as ( SELECT * from SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.CUSTOMER LIMIT 5000 );
查询输入表以查看数据,并确认每个表是否都有 5,000 行:
USE WAREHOUSE syndata_wh; SELECT TOP 20 * FROM syndata_db.sch.TPC_ORDERS_5K; SELECT COUNT(*) FROM syndata_db.sch.TPC_ORDERS_5K; select count(distinct o_clerk), count(*) from syndata_db.sch.TPC_ORDERS_5K; SELECT TOP 20 * FROM syndata_db.sch.TPC_CUSTOMERS_5K; SELECT COUNT(*) FROM syndata_db.sch.TPC_CUSTOMERS_5K;
调用 GENERATE_SYNTHETIC_DATA 存储过程,将合成数据生成到两个输出表中。指定联接键,因为您稍后将使用这些键进行联接。
CALL SNOWFLAKE.DATA_PRIVACY.GENERATE_SYNTHETIC_DATA({ 'datasets':[ { 'input_table': 'syndata_db.sch.TPC_ORDERS_5K', 'output_table': 'syndata_db.sch.TPC_ORDERS_5K_SYNTHETIC', 'columns': {'O_CUSTKEY': {'join_key': True}} }, { 'input_table': 'syndata_db.sch.TPC_CUSTOMERS_5K', 'output_table': 'syndata_db.sch.TPC_CUSTOMERS_5K_SYNTHETIC', 'columns' : {'C_CUSTKEY': {'join_key': True}} } ], 'replace_output_tables':True });
查询输出表以查看合成数据:
SELECT TOP 20 * FROM syndata_db.sch.TPC_ORDERS_5K_SYNTHETIC; SELECT COUNT(*) FROM syndata_db.sch.TPC_ORDERS_5K_SYNTHETIC; SELECT TOP 20 * FROM syndata_db.sch.TPC_CUSTOMERS_5K_SYNTHETIC; SELECT COUNT(*) FROM syndata_db.sch.TPC_CUSTOMERS_5K_SYNTHETIC;
清理所有对象
USE ROLE ACCOUNTADMIN; DROP DATABASE syndata_db; DROP ROLE data_engineer; DROP WAREHOUSE syndata_wh;