2. Snowflake元数据体系解析

在Snowflake中做数据质量与元数据治理,第一步不是写规则,而是先搞清楚“元数据从哪里来、能看到什么、延迟多久、权限怎么控”。Snowflake把元数据分成两条主线:一条是INFORMATION_SCHEMA,随数据库存在、只覆盖当前数据库、实时性强;另一条是ACCOUNT_USAGE,位于共享数据库SNOWFLAKE中、覆盖整个账户、有延迟但保留历史。理解这两条主线的差异,是后续所有血缘分析、质量监控和成本治理的基础。

一、两条元数据主线的定位差异

INFORMATION_SCHEMA是每个数据库自带的模式,命名规则为<数据库名>.INFORMATION_SCHEMA。它只描述当前数据库内的对象,查询结果几乎实时反映DDL变更,适合做“当前状态”的即时校验。ACCOUNT_USAGE位于SNOWFLAKE.ACCOUNT_USAGE,是账户级共享视图,覆盖所有数据库、所有对象,并保留历史快照,但存在延迟:大多数视图延迟约45分钟到3小时,且不包含被删除对象在删除前的最后状态之外的更多细节。

一个常见的误区是:用INFORMATION_SCHEMA去查跨库血缘,或用ACCOUNT_USAGE去查“刚刚创建的表”。前者查不到,后者可能还没刷新。正确做法是——即时校验用INFORMATION_SCHEMA,历史趋势与跨库分析用ACCOUNT_USAGE。

Snowflake 元数据双主线结构 INFORMATION_SCHEMA(数据库级·实时) TABLES / COLUMNS / VIEWS TABLE_CONSTRAINTS / REFERENTIAL_CONSTRAINTS COLUMNS 中的 IS_NULLABLE / DATA_TYPE OBJECT_DEPENDENCIES(库内血缘) TASK_HISTORY / COPY_HISTORY(库内) 特点 • 仅当前数据库,不跨库 • DDL 后几乎立即可见 • 无历史保留,只反映当前 • 权限随数据库 USAGE 授予 ACCOUNT_USAGE(账户级·延迟) TABLES / COLUMNS(全账户) OBJECT_DEPENDENCIES(跨库血缘) QUERY_HISTORY / ACCESS_HISTORY WAREHOUSE_METERING_HISTORY TASK_HISTORY / COPY_HISTORY(账户) 特点 • 覆盖全账户,可跨库分析 • 延迟约 45 分钟 ~ 3 小时 • 保留历史,可做趋势 • 需 GRANT IMPORTED PRIVILEGES 即时校验 历史/跨库

二、OBJECT_DEPENDENCIES:血缘分析的核心视图

OBJECT_DEPENDENCIES是血缘治理最常用的视图,它记录对象之间的引用关系。关键字段包括:REFERENCING_OBJECT_NAME(引用方,如视图、任务)、REFERENCED_OBJECT_NAME(被引用方,如表、视图)、REFERENCING_OBJECT_DOMAIN与REFERENCED_OBJECT_DOMAIN(对象类型,如TABLE、VIEW、TASK)。

在INFORMATION_SCHEMA中,OBJECT_DEPENDENCIES只显示当前数据库内的依赖;在ACCOUNT_USAGE中,它显示跨库依赖,但延迟较高。下面是一个查询示例,用于找出某张表被哪些视图引用:

SELECT
  REFERENCING_OBJECT_NAME AS view_name,
  REFERENCING_OBJECT_DOMAIN AS view_type,
  REFERENCED_OBJECT_NAME AS source_table,
  REFERENCED_OBJECT_DOMAIN AS source_type
FROM SNOWFLAKE.ACCOUNT_USAGE.OBJECT_DEPENDENCIES
WHERE REFERENCED_OBJECT_NAME = 'SALES_ORDERS'
  AND REFERENCED_OBJECT_DOMAIN = 'TABLE'
ORDER BY view_name;

如果只想查当前库内的即时依赖,把FROM换成MY_DB.INFORMATION_SCHEMA.OBJECT_DEPENDENCIES即可,结果几乎实时,但看不到跨库引用。

三、INFORMATION_SCHEMA中做数据质量探查的常用视图

数据质量治理中,最常查的是COLUMNS视图。它包含TABLE_NAME、COLUMN_NAME、DATA_TYPE、IS_NULLABLE、COLUMN_DEFAULT、CHARACTER_MAXIMUM_LENGTH等字段。通过它可以在写规则前先做“结构体检”:哪些列允许NULL、哪些列没有默认值、哪些列类型与预期不符。

例如,找出某张表中所有允许NULL的列,用于判断是否需要加NOT NULL约束:

SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, IS_NULLABLE
FROM MY_DB.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'PUBLIC'
  AND TABLE_NAME = 'CUSTOMER_DIM'
  AND IS_NULLABLE = 'YES'
ORDER BY ORDINAL_POSITION;

另一个常用视图是TABLE_CONSTRAINTS与REFERENTIAL_CONSTRAINTS,用于检查主键、唯一键、外键是否缺失。Snowflake的标准表不强制主键,但声明主键对优化器与治理都有价值。通过这两个视图可以快速盘点“哪些表没有主键”。

四、ACCOUNT_USAGE中的历史与行为元数据

ACCOUNT_USAGE的价值在于“历史”和“行为”。QUERY_HISTORY记录每次查询的执行情况,包括QUERY_TEXT、EXECUTION_STATUS、TOTAL_ELAPSED_TIME、ROWS_PRODUCED等,可用于回溯某张表在某个时间点被谁查过、是否失败。ACCESS_HISTORY则记录列级访问,能回答“哪些列从未被查询过”,这对识别冗余列、优化存储很有帮助。

需要注意的是,ACCOUNT_USAGE视图有保留期限:QUERY_HISTORY默认保留365天,ACCESS_HISTORY保留365天,超出后自动清理。因此做长期治理时,应定期把关键元数据落地到自建表中。

权限提示:查询ACCOUNT_USAGE需要GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE TO ROLE <角色名>。默认只有ACCOUNTADMIN拥有,建议为治理角色单独授予,避免过度使用ACCOUNTADMIN。

五、查询方法与实践建议

在实际治理中,建议按以下顺序组织查询:先用INFORMATION_SCHEMA做即时结构盘点,确认当前对象状态;再用ACCOUNT_USAGE做历史趋势与跨库血缘;最后把两者结果按对象名对齐,形成“当前状态+历史行为”的完整画像。

一个常见的对齐方式是:以TABLE_CATALOG.TABLE_SCHEMA.TABLE_NAME为键,把INFORMATION_SCHEMA.COLUMNS的当前列信息,与ACCOUNT_USAGE.ACCESS_HISTORY的访问记录做关联,从而判断“某列存在但从未被访问”。这种查询在治理初期能快速定位低价值列。

最后提醒:ACCOUNT_USAGE的延迟意味着它不适合做实时告警。如果需要“表被删除后立即感知”,应依赖INFORMATION_SCHEMA的即时查询或事件通知,而不是等待ACCOUNT_USAGE刷新。把两条主线的定位分清,元数据治理的查询效率会显著提升。