4. 准备共享环境

在 Snowflake 中做数据共享,最容易踩的坑不是 CREATE SHARE 本身,而是把共享对象挂在日常业务角色和仓库上。共享一旦对外发布,消费方会持续查询,如果共用生产仓库,就可能挤占 ETL 资源;如果共用 SYSADMIN 或业务角色,权限边界会变得模糊,后续审计也说不清“谁把哪张表共享出去了”。因此,正式创建共享之前,应先搭好一套共享专用环境:专用角色、专用虚拟仓库、专用数据库与架构,再叠加权限和资源监控。

本节以一家零售企业为例:数据团队需要把 SALES_DB.ANALYTICS 下的订单汇总表共享给外部合作方。我们按“角色 → 仓库 → 数据库/架构 → 权限 → 监控”的顺序落地,每一步都给出可执行的 SQL 与判断依据。

一、创建共享专用角色

共享角色应遵循最小权限原则,只负责“持有并发布共享对象”,不参与日常数据加工。建议创建两个角色:SHARE_ADMIN 负责创建和管理共享,SHARE_READER 作为被授予共享对象权限的载体角色。

USE ROLE SECURITYADMIN;

CREATE ROLE IF NOT EXISTS SHARE_ADMIN
  COMMENT = '管理共享定义与授权,不参与数据加工';

CREATE ROLE IF NOT EXISTS SHARE_READER
  COMMENT = '承载被共享对象的读取权限';

-- 角色继承:让 SHARE_ADMIN 能管理 SHARE_READER
GRANT ROLE SHARE_READER TO ROLE SHARE_ADMIN;

-- 授予给实际运维人员(示例用户)
GRANT ROLE SHARE_ADMIN TO USER dba_li;

这里的关键判断是:不要把 SHARE_ADMIN 授予 SYSADMIN,也不要让共享角色继承业务角色。共享角色只应看到“准备共享出去的对象”,这样即使共享配置出错,影响面也被限制在共享范围内。

二、创建共享专用虚拟仓库

消费方查询共享数据时,计算资源由消费方自己的仓库承担,但共享方在准备阶段(如验证共享视图、生成样例数据)仍需要一个专用仓库。更重要的是,如果共享中包含安全视图或需要物化的对象,共享方的仓库配置会影响准备效率。

USE ROLE SYSADMIN;

CREATE WAREHOUSE IF NOT EXISTS WH_SHARE_XS
  WAREHOUSE_SIZE = 'XSMALL'
  AUTO_SUSPEND = 60
  AUTO_RESUME = TRUE
  INITIALLY_SUSPENDED = TRUE
  COMMENT = '共享准备与验证专用,60 秒无活动自动挂起';

GRANT USAGE ON WAREHOUSE WH_SHARE_XS TO ROLE SHARE_ADMIN;

参数选择依据:共享准备多为元数据操作和少量验证查询,XSMALL 足够;AUTO_SUSPEND = 60 可避免仓库空转计费;INITIALLY_SUSPENDED = TRUE 保证创建后不立即消耗信用点。若共享对象包含大表全量校验,可临时调大规格,验证完成后调回。

三、创建共享专用数据库与架构

共享对象不应直接放在生产库中。推荐做法是建立独立的共享数据库,通过安全视图引用生产数据,实现物理隔离与列级脱敏。

USE ROLE SYSADMIN;

CREATE DATABASE IF NOT EXISTS SHARE_DB
  COMMENT = '对外共享专用数据库';

CREATE SCHEMA IF NOT EXISTS SHARE_DB.PARTNER_OUT
  COMMENT = '合作方共享对象架构';

-- 授权给共享角色
GRANT USAGE ON DATABASE SHARE_DB TO ROLE SHARE_ADMIN;
GRANT USAGE ON SCHEMA SHARE_DB.PARTNER_OUT TO ROLE SHARE_ADMIN;
GRANT CREATE VIEW ON SCHEMA SHARE_DB.PARTNER_OUT TO ROLE SHARE_ADMIN;

接着在 SHARE_DB.PARTNER_OUT 中创建安全视图,引用生产表并做字段裁剪:

USE ROLE SHARE_ADMIN;
USE WAREHOUSE WH_SHARE_XS;

CREATE OR REPLACE SECURE VIEW SHARE_DB.PARTNER_OUT.V_ORDER_SUMMARY AS
SELECT
  order_date,
  region,
  channel,
  SUM(order_amount) AS total_amount,
  COUNT(DISTINCT order_id) AS order_cnt
FROM SALES_DB.ANALYTICS.ORDERS
WHERE order_date >= '2024-01-01'
GROUP BY order_date, region, channel;

使用 SECURE VIEW 的原因:它会隐藏视图定义,消费方无法通过 GET_DDL 反推底层表结构;同时可在视图中过滤敏感字段(如客户手机号),实现“共享汇总、不共享明细”。

四、配置权限并验证

权限配置的核心是:共享角色只对共享对象有权限,且只授予必要的 USAGE 和 SELECT。

USE ROLE SECURITYADMIN;

-- 让 SHARE_READER 能读取共享视图
GRANT USAGE ON DATABASE SHARE_DB TO ROLE SHARE_READER;
GRANT USAGE ON SCHEMA SHARE_DB.PARTNER_OUT TO ROLE SHARE_READER;
GRANT SELECT ON VIEW SHARE_DB.PARTNER_OUT.V_ORDER_SUMMARY TO ROLE SHARE_READER;

-- 验证:以 SHARE_READER 身份查询
USE ROLE SHARE_READER;
SELECT * FROM SHARE_DB.PARTNER_OUT.V_ORDER_SUMMARY LIMIT 5;

验证判断依据:若查询返回数据,说明权限链路(角色 → 数据库 → 架构 → 视图)已打通;若报 Insufficient privileges,按层级逐级检查 SHOW GRANTS TO ROLE SHARE_READER,定位缺失的 USAGE 或 SELECT。

五、配置资源监控

共享准备阶段虽以元数据操作为主,但仍需监控仓库消耗,避免验证查询失控。使用 RESOURCE MONITOR 设置信用点阈值和通知。

USE ROLE ACCOUNTADMIN;

CREATE OR REPLACE RESOURCE MONITOR RM_SHARE
  WITH CREDIT_QUOTA = 20
  FREQUENCY = MONTHLY
  START_TIMESTAMP = IMMEDIATELY
  TRIGGERS
    ON 75 PERCENT DO NOTIFY
    ON 100 PERCENT DO SUSPEND;

ALTER WAREHOUSE WH_SHARE_XS SET RESOURCE_MONITOR = RM_SHARE;

阈值设计依据:XSMALL 仓库每小时约消耗 1 个信用点,20 个信用点/月足够共享准备与验证;75% 触发通知便于提前干预,100% 自动挂起防止超额。监控生效后,可通过 SELECT * FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY WHERE WAREHOUSE_NAME = 'WH_SHARE_XS' 查看实际消耗。

共享专用环境搭建:角色 · 仓库 · 数据库/架构 · 权限 · 监控 共享专用角色 SHARE_ADMIN SHARE_READER 共享专用仓库 WH_SHARE_XS XSMALL · 60s 自动挂起 共享专用数据库与架构 SHARE_DB PARTNER_OUT SECURE VIEW 隔离生产数据 权限授予链路(逐级 USAGE + SELECT) SHARE_READER USAGE ON DB USAGE ON SCHEMA SELECT ON VIEW 资源监控:RM_SHARE(月度 20 信用点) 75% → NOTIFY 提前预警 100% → SUSPEND 自动挂起仓库 METERING_HISTORY 查看实际消耗

六、常见问题与检查要点

  • 共享角色被授予了业务角色:会导致权限扩散,应保持共享角色独立,仅通过 GRANT ROLE SHARE_READER TO ROLE SHARE_ADMIN 建立管理关系。
  • 直接共享生产表而非安全视图:消费方可能看到敏感列,且无法隐藏底层结构,应统一使用 SECURE VIEW。
  • 忘记授予架构级 USAGE:只授予数据库 USAGE 不够,必须逐级授予 USAGE ON SCHEMA,否则查询报权限不足。
  • 资源监控未绑定仓库:创建 RESOURCE MONITOR 后必须执行 ALTER WAREHOUSE ... SET RESOURCE_MONITOR,否则监控不生效。
建议在共享环境搭建完成后,执行一次“最小权限验证”:用 SHARE_READER 查询共享视图应成功,查询生产表 SALES_DB.ANALYTICS.ORDERS 应失败。两条结果同时满足,才说明权限边界正确。

完成以上五步后,共享环境就具备了清晰的边界:SHARE_ADMIN 管共享、SHARE_READER 承载读取权限、WH_SHARE_XS 承担准备计算、SHARE_DB.PARTNER_OUT 存放安全视图、RM_SHARE 控制成本。后续创建 SHARE 对象时,只需把 SHARE_DB.PARTNER_OUT 中的视图授予共享即可,权限和资源都已就位。