Snowflake自动数据分类:PII检测完整指南
DataHot 速览
Snowflake技术架构师撰写的完整指南,介绍如何在数据仓库内原生自动发现、分类和保护敏感数据。方案基于机器学习分析列数据模式与元数据,无需外部工具、无需数据移动。文中涵盖手动分类、自定义分类器、分类配置、自动化启用、合规查询以及基于标签的脱敏策略集成等操作细节。
为什么值得关注:数据从业者可了解Snowflake内置治理能力的自动化PII识别流程,以及分类结果如何与脱敏策略联动,是平台化数据治理的落地参考。
本文目录 35 节
- 自动化PII检测完全指南
- 引言
- 您将学到什么
- 先决条件
- 第1节:核心概念
- 两种分类方法
- 语义类别(内置)
- 隐私类别:
- 第2节:使用SYSTEM$CLASSIFY进行手动分类
- 设置示例数据
- 运行分类
- 解析结果
- 已验证结果:CUSTOMER_RECORDS
- 已验证结果:EMPLOYEE_DIRECTORY
- 已验证结果:MEDICAL_RECORDS
- 第3节:自定义分类器
- 创建自定义分类器
- ADD_REGEX参数
- 使用自定义分类器
- 已知限制
- 第4节:分类配置文件与自动分类
- 创建配置文件
- 配置文件参数
- 启用自动分类
- 自动分类管道
- 第5节:监控与合规性仪表板
- 高管摘要查询
- GDPR合规性报告
- 第6节:与基于标记的脱敏集成
- 自动化保护管道
- 第7节:最佳实践与陷阱
- 最佳实践
- 常见陷阱
- 所需权限
- 结论
译文
AI 逐段翻译自动化PII检测完全指南
如何在你的整个数据仓库中自动发现、分类并保护敏感数据
免责声明:我是Snowflake的首席技术架构师 拥有超过30年的数据战略、架构和开发经验。此处表达的观点仅代表我个人,并不一定反映我现在、以前或未来雇主的观点
引言
每个组织都存储敏感数据——姓名、电子邮件、社会安全号码、信用卡号码、薪资信息。挑战在于知道这些数据存在于数百张表和数千列中的哪些位置。传统方法需要手动审计、正则表达式脚本或昂贵的外部工具,在仓库之外扫描数据。
Snowflake的内置数据分类通过提供原生的、平台内的PII检测解决了这个问题,无需外部工具、零数据移动和零Python代码。它使用机器学习分析列数据模式和元数据,以高置信度识别敏感信息。
在本指南中,我们将介绍完整的工作流程:从一次性手动扫描到完全自动化的持续监控,包括自动标记和基于标记的脱敏集成。
警告:"这将对您账户中所有已收到语义类别标记的STRING列应用脱敏策略。请先验证范围:"
SELECT * FROM SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES WHERE TAG_NAME = 'SEMANTIC_CATEGORY'您将学到什么
- 使用SYSTEM$CLASSIFY进行手动分类
- 读取和解析分类结果
- 为特定领域数据创建自定义分类器
- 设置用于自动化的分类配置文件
- 在数据库上启用自动分类
- 查询DATA_CLASSIFICATION_LATEST以用于合规性仪表板
- 将分类与基于标记的脱敏策略集成
先决条件
开始之前,请确保您拥有:
- SYSADMIN或等效角色,具有对目标表的SELECT权限
- 对目标表具有SELECT权限;此外,当使用auto_tag: true时,对模式拥有OWNERSHIP权限。
- SNOWFLAKE.CLASSIFICATION_ADMIN数据库角色(用于创建配置文件)
- 一个活动的仓库
第1节:核心概念
两种分类方法
Snowflake提供了两种数据分类方法:
语义类别(内置)
Snowflake开箱即用地识别以下数据类型:

隐私类别:

第2节:使用SYSTEM$CLASSIFY进行手动分类
设置示例数据
我们创建三个代表常见企业数据的表,包含PII:
- Create schema
CREATE SCHEMA IF NOT EXISTS AGUHA_DB.CLASSIFICATION;
USE SCHEMA AGUHA_DB.CLASSIFICATION;
-- Customer records with retail PII
CREATE OR REPLACE TABLE CUSTOMER_RECORDS (
customer_id INT,
first_name VARCHAR(50),
last_name VARCHAR(50),
email VARCHAR(100),
phone_number VARCHAR(20),
date_of_birth DATE,
ssn VARCHAR(11),
street_address VARCHAR(200),
city VARCHAR(50),
state VARCHAR(2),
zip_code VARCHAR(10),
credit_card_number VARCHAR(19),
account_balance DECIMAL(12,2),
signup_date DATE
);运行分类
SYSTEM$CLASSIFY使用CALL调用(绝不能使用SELECT)。它恰好接受2个参数:
- 参数1:完全限定的表名(必需)
- 参数2:NULL(默认值)、配置文件字符串或选项对象
使用默认值进行基本分类
CALL SYSTEM$CLASSIFY('AGUHA_DB.CLASSIFICATION.CUSTOMER_RECORDS', null);带采样控制
CALL SYSTEM$CLASSIFY('AGUHA_DB.CLASSIFICATION.CUSTOMER_RECORDS', {'sample_count': 1000});分类后自动应用标记
CALL SYSTEM$CLASSIFY('AGUHA_DB.CLASSIFICATION.CUSTOMER_RECORDS', {'auto_tag': true});关键:第2个参数要么是配置文件字符串,要么是选项对象——绝不能同时使用。不存在3参数形式。
解析结果
分类结果以JSON格式存储。使用FLATTEN进行解析:
SELECT
f.key AS column_name,
f.value:recommendation:semantic_category::VARCHAR AS semantic_category,
f.value:recommendation:privacy_category::VARCHAR AS privacy_category,
f.value:recommendation:confidence::VARCHAR AS confidence
FROM TABLE(FLATTEN(
INPUT => PARSE_JSON(
SYSTEM$GET_CLASSIFICATION_RESULT(
'AGUHA_DB.CLASSIFICATION.CUSTOMER_RECORDS'
)
):classification_result
)) f
WHERE f.value:recommendation:semantic_category IS NOT NULL
ORDER BY column_name;已验证结果:CUSTOMER_RECORDS
运行上述操作产生以下结果(已在Snowflake上验证):

值得注意的是:Snowflake正确识别了14列中的10列包含PII。CUSTOMER_ID、CREDIT_CARD_NUMBER、ACCOUNT_BALANCE和SIGNUP_DATE未被分类。
已验证结果:EMPLOYEE_DIRECTORY

关键见解:EMP_ID和MANAGER_EMP_ID未被检测到,因为它们使用自定义的公司特定格式(EMP-XXXXX)。这正是自定义分类器存在的原因。
已验证结果:MEDICAL_RECORDS

与HIPAA相关:PATIENT_ID、INSURANCE_ID、DIAGNOSIS_CODE和PRESCRIPTION未被分类——这些需要自定义分类器。
第3节:自定义分类器
Snowflake的内置分类覆盖了常见的PII。但组织具有特定领域的标识符:
- 员工ID:EMP-10001、STAFF_001
- 患者ID:PAT-2024-001、MRN-12345
- 项目代码:PRJ-ENG-001
- 保险ID:INS-BC-12345
创建自定义分类器
- Step 1: Create the classifier instance
CREATE OR REPLACE SNOWFLAKE.DATA_PRIVACY.CUSTOM_CLASSIFIER
AGUHA_DB.CLASSIFICATION.EMPLOYEE_ID_CLASSIFIER();
- Step 2: Add regex pattern(s)
CALL AGUHA_DB.CLASSIFICATION.EMPLOYEE_ID_CLASSIFIER!ADD_REGEX(
'EMPLOYEE_ID', -- semantic_category
'IDENTIFIER', -- privacy_category
'EMP-[0-9]{5}', -- value_regex
'emp|employee', -- col_name_regex
'Detects employee IDs in format EMP-XXXXX',
0.8 - threshold
);
- Add another pattern
CALL AGUHA_DB.CLASSIFICATION.EMPLOYEE_ID_CLASSIFIER!ADD_REGEX(
'PATIENT_ID',
'IDENTIFIER',
'PAT-[0-9]{4}-[0-9]{3}',
'patient|pat',
'Detects patient IDs in format PAT-YYYY-NNN',
0.8
);ADD_REGEX参数

使用自定义分类器
-- Use specific classifier
CALL SYSTEM$CLASSIFY('AGUHA_DB.CLASSIFICATION.EMPLOYEE_DIRECTORY',
{'custom_classifiers': ['AGUHA_DB.CLASSIFICATION.EMPLOYEE_ID_CLASSIFIER']});
- Use ALL custom classifiers
CALL SYSTEM$CLASSIFY('AGUHA_DB.CLASSIFICATION.EMPLOYEE_DIRECTORY',
{'use_all_custom_classifiers': true});
- Verify patterns
SELECT AGUHA_DB.CLASSIFICATION.EMPLOYEE_ID_CLASSIFIER!LIST();
-- Note: Snowflake instance method call returning a VARIANT, not a standard SELECT已知限制
- 自定义分类器需要50行以上才能可靠检测
- 小数据集(少于10行)可能无法达到阈值
- 当数据量较低时,列名正则表达式提供次要信号
第4节:分类配置文件与自动分类
分类配置文件将一次性扫描转变为持续监控。一旦附加到数据库,Snowflake会自动分类新表和修改后的表。
创建配置文件
CREATE OR REPLACE SNOWFLAKE.DATA_PRIVACY.CLASSIFICATION_PROFILE
AGUHA_DB.CLASSIFICATION.PII_MONITOR(
{
'minimum_object_age_for_classification_days': 1,
'maximum_classification_validity_days': 30,
'auto_tag': FALSE
}
);
-- Verify
SELECT AGUHA_DB.CLASSIFICATION.PII_MONITOR!DESCRIBE();配置文件参数

启用自动分类
- Attach profile to entire database
ALTER DATABASE AGUHA_DB
SET CLASSIFICATION_PROFILE = 'AGUHA_DB.CLASSIFICATION.PII_MONITOR';
- Or attach to a specific schema only
ALTER SCHEMA AGUHA_DB.CLASSIFICATION
SET CLASSIFICATION_PROFILE = 'AGUHA_DB.CLASSIFICATION.PII_MONITOR';
- Check monitored entities
SELECT SYSTEM$SHOW_SENSITIVE_DATA_MONITORED_ENTITIES('DATABASE');
- Disable
ALTER DATABASE AGUHA_DB UNSET CLASSIFICATION_PROFILE;自动分类管道
当auto_tag = TRUE时:
- 新表创建或现有表修改
- 在minimum_object_age天之后,Snowflake自动进行分类
- 将语义标记应用于检测到的列
- 基于标记的脱敏策略自动激活
- 零人工干预保护数据
第5节:监控与合规性仪表板
结果存储在SNOWFLAKE.ACCOUNT_USAGE.DATA_CLASSIFICATION_LATEST中。
先决条件:
- SNOWFLAKE.CORE_VIEWER数据库角色(用于SYSTEM$CLASSIFY)
高管摘要查询
SELECT
DATABASE_NAME,
COUNT(DISTINCT TABLE_ID) AS tables_classified,
COUNT(DISTINCT CASE WHEN f.VALUE:recommendation:privacy_category::STRING = 'IDENTIFIER' THEN f.KEY END) AS identifier_columns,
COUNT(DISTINCT CASE WHEN f.VALUE:recommendation:privacy_category::STRING = 'QUASI_IDENTIFIER' THEN f.KEY END) AS quasi_identifier_columns
FROM SNOWFLAKE.ACCOUNT_USAGE.DATA_CLASSIFICATION_LATEST,
LATERAL FLATTEN(INPUT => RESULT) f
WHERE f.VALUE:recommendation:semantic_category IS NOT NULL
GROUP BY DATABASE_NAME;GDPR合规性报告
SELECT
DATABASE_NAME || '.' || SCHEMA_NAME || '.' || TABLE_NAME AS table_path,
f.KEY AS column_name,
f.VALUE:recommendation:semantic_category::STRING AS category
FROM SNOWFLAKE.ACCOUNT_USAGE.DATA_CLASSIFICATION_LATEST,
LATERAL FLATTEN(INPUT => RESULT) f
WHERE f.VALUE:recommendation:privacy_category::STRING = 'IDENTIFIER'
AND f.VALUE:recommendation:confidence::STRING = 'HIGH'
ORDER BY table_path, column_name;第6节:与基于标记的脱敏集成
与基于标记的脱敏结合时,真正的力量才会显现。当启用auto_tag时,被分类的列会收到系统标记。将脱敏策略附加到这些标记上,实现完全自动化的保护。
自动化保护管道
- Create masking policy
CREATE OR REPLACE MASKING POLICY AGUHA_DB.CLASSIFICATION.PII_STRING_MASK
AS (val STRING) RETURNS STRING ->
CASE
WHEN IS_ROLE_IN_SESSION('PII_ADMIN') THEN val
WHEN IS_ROLE_IN_SESSION('PII_VIEWER') THEN LEFT(val, 2) || '***' || RIGHT(val, 2)
ELSE '***MASKED***'
END;
-- Attach to semantic category tag
-- Step 1: Masking policy on YOUR tag (already created and verified)
ALTER TAG AGUHA_DB.CLASSIFICATION.PII_CATEGORY
SET MASKING POLICY AGUHA_DB.CLASSIFICATION.PII_STRING_MASK;
-- Step 2: Classification Profile maps SEMANTIC_CATEGORY → your tag automatically
CREATE OR REPLACE SNOWFLAKE.DATA_PRIVACY.CLASSIFICATION_PROFILE
AGUHA_DB.CLASSIFICATION.PII_AUTO_PROFILE(
{
'minimum_object_age_for_classification_days': 0,
'maximum_classification_validity_days': 30,
'auto_tag': true,
'tag_map': {
'column_tag_map': [
{
'tag_name': 'AGUHA_DB.CLASSIFICATION.PII_CATEGORY',
'tag_value': 'PII',
'semantic_categories': ['NAME', 'EMAIL', 'PHONE_NUMBER', 'NATIONAL_IDENTIFIER']
},
{
'tag_name': 'AGUHA_DB.CLASSIFICATION.PII_CATEGORY',
'tag_value': 'SENSITIVE',
'semantic_categories': ['PAYMENT_CARD', 'BANK_ACCOUNT', 'SALARY']
},
{
'tag_name': 'AGUHA_DB.CLASSIFICATION.PII_CATEGORY',
'tag_value': 'IDENTIFIER',
'semantic_categories': ['US_SSN', 'PASSPORT', 'DRIVERS_LICENSE']
}
]
}
}
);管道:新数据 -> 自动分类 -> 标记 -> 脱敏 零手动干预!
第7节:最佳实践与陷阱
最佳实践
先手动,后自动化:首先运行SYSTEM$CLASSIFY。在启用auto_tag=TRUE之前进行审查。
使用auto_tag=FALSE进行测试:自动标记会永久修改模式元数据。
为领域数据使用自定义分类器:内置覆盖约80%。员工ID、内部代码需要自定义。
设置适当的有效期:活动:30天。合规性:14天。归档:90天。
与基于标记的脱敏结合:自动分类 + 自动标记 + 基于标记的脱敏 = 零接触保护。
常见陷阱
- 使用SELECT而不是CALL -> “未知函数”错误
- 同时传递配置文件和选项 -> 不存在3参数形式
- 在CREATE之前忘记模式上下文 -> 位置错误
- 小数据(少于10行)-> 未达到自定义分类器阈值
- 结果嵌套在 :classification_result 键下,而非根级别
所需权限
结论
Snowflake 的自动数据分类消除了对外部扫描工具、自定义 Python 脚本或手动数据审计的需求。通过三个组件——SYSTEM$CLASSIFY、分类配置文件和自定义分类器——您可以构建一个完全自动化的治理管道,该管道:
- 自动发现整个仓库中的个人身份信息
- 使用语义类别标记敏感列
- 通过基于标签的绑定激活掩码策略
- 按计划重新分类以捕获新的敏感数据
- 通过 ACCOUNT_USAGE 视图提供合规性仪表板
结果:随着数据扩展而扩展的零接触数据保护。无需 Airflow DAG、无需外部 API、无需维护。只需要 SQL 和 Snowflake 在本地管理治理。
Snowflake 自动数据分类最初发布于Snowflake Builders Blog: Data Engineers, App Developers, AI, & Data Science在 Medium 上,人们在那里通过强调和回应这个故事来继续对话。
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏