2. Snowflake共享架构解析
要真正理解 Snowflake 数据共享,不能只记住“把数据分享出去”这句话,而必须弄清楚共享链路上每一个对象分别扮演什么角色、受什么边界约束。Snowflake 的共享不是把文件复制给对方,而是由提供方在自身账户内定义一组可被消费的数据库对象,再通过共享(Share)这一逻辑容器,把访问权限授予另一个账户。理解账户、区域、云平台、数据库、架构、表在其中的位置,是判断“能不能共享、共享后对方看到什么、为什么有时共享不可用”的基础。
一、共享链路上的对象层级
从提供方视角看,共享的对象层级自外向内依次是:账户(Account)→ 数据库(Database)→ 架构(Schema)→ 表/视图(Table/View)。共享(Share)本身是一个独立的账户级对象,它不存放数据,只存放“授权清单”:允许哪些账户访问哪些数据库、架构和表。消费方账户通过 CREATE DATABASE ... FROM SHARE 在自己的账户里创建一个只读数据库,这个数据库是共享对象的“投影”,其内部对象由提供方决定,消费方不能修改。
需要特别注意的是,共享的授权粒度可以到表或视图级别,但消费方看到的层级结构必须与提供方一致。也就是说,提供方共享了 SALES_DB.ORDERS_SCHEMA.ORDERS,消费方看到的也是同名数据库、同名架构下的同名表,只是它位于消费方账户内、标记为只读。这种“结构对齐、数据不落地”的特性,是 Snowflake 共享区别于传统 ETL 抽取的核心。
二、账户与区域:共享的“身份边界”
账户是 Snowflake 中最高一级的隔离单位,也是共享的授权主体。共享只能在账户之间建立,不能跨组织边界随意扩散。每个账户归属于一个特定区域(Region)和云平台(Cloud Platform),例如 AWS us-west-2、Azure East US 2、GCP us-central1。区域和云平台共同决定了数据物理存储位置与计算资源位置。
这就带来一个关键边界:默认情况下,共享要求提供方与消费方位于同一区域、同一云平台。如果消费方账户在另一个区域,直接共享会失败或不可见。要跨越这一边界,需要借助 Snowflake 的跨区域复制(Replication)或跨云自动满足机制,把共享对象复制到目标区域后再共享。因此,在设计共享方案前,第一件事就是确认双方账户的区域与云平台是否一致,这是很多“共享建好了但对方看不到”问题的根因。
三、数据库、架构、表:共享的“内容边界”
共享的内容边界由数据库、架构、表三层共同决定。提供方在共享中授予的是具体对象的使用权,通常包括:对数据库的 USAGE、对架构的 USAGE、对表或视图的 SELECT。三者缺一不可——只授予表的 SELECT 而不授予数据库和架构的 USAGE,消费方仍然无法访问。
表是共享的最小数据单元,视图则提供了更灵活的共享方式。通过视图,提供方可以只暴露部分列、过滤敏感行、做聚合汇总,而不必共享整张基表。例如,提供方可以共享一个只包含订单金额区间统计的视图,而不共享含客户手机号的明细表。这种“以视图为共享边界”的做法,是控制数据暴露面的常用手段。
需要强调的是,共享对象在消费方是只读的。消费方不能对共享表执行 INSERT、UPDATE、DELETE,也不能修改其结构。消费方可以基于共享表创建自己的视图或物化视图,但原始共享对象始终由提供方掌控。提供方一旦撤销授权,消费方的访问立即失效。
四、共享中的角色与权限边界
在账户内部,共享的创建与授权由具备相应权限的角色完成。通常由 ACCOUNTADMIN 或拥有 CREATE SHARE 权限的角色创建共享,再由对象所有者角色执行 GRANT ... TO SHARE。消费方则需要由具备 CREATE DATABASE 权限的角色执行 CREATE DATABASE ... FROM SHARE,并为最终用户角色授予对该只读数据库的访问权限。
这里存在两条清晰的边界:一是账户边界,共享只发生在账户之间,账户内的角色权限不能直接跨账户生效;二是对象边界,共享只覆盖被显式授予的对象,未授予的表、架构、数据库对消费方完全不可见。理解这两条边界,就能解释为什么消费方“只看到一部分表”、为什么“撤销授权后立刻查不到数据”。
五、一个可对照的共享配置示例
下面给出一个典型的共享配置片段,帮助把上述对象关系落到具体语句上。示例中提供方共享 SALES_DB.ORDERS_SCHEMA 下的 ORDERS 表和 V_ORDER_SUMMARY 视图,消费方账户为 CONSUMER_ACCT。
-- 提供方:创建共享并授权
CREATE SHARE SALES_SHARE;
GRANT USAGE ON DATABASE SALES_DB TO SHARE SALES_SHARE;
GRANT USAGE ON SCHEMA SALES_DB.ORDERS_SCHEMA TO SHARE SALES_SHARE;
GRANT SELECT ON TABLE SALES_DB.ORDERS_SCHEMA.ORDERS TO SHARE SALES_SHARE;
GRANT SELECT ON VIEW SALES_DB.ORDERS_SCHEMA.V_ORDER_SUMMARY TO SHARE SALES_SHARE;
ALTER SHARE SALES_SHARE ADD ACCOUNT = CONSUMER_ACCT;
-- 消费方:从共享创建只读数据库
CREATE DATABASE SALES_DB FROM SHARE PROVIDER_ACCT.SALES_SHARE;
-- 消费方:验证可见对象
SHOW TABLES IN SCHEMA SALES_DB.ORDERS_SCHEMA;
SELECT COUNT(*) FROM SALES_DB.ORDERS_SCHEMA.ORDERS;
执行后,消费方应能在 SALES_DB.ORDERS_SCHEMA 下看到 ORDERS 和 V_ORDER_SUMMARY,而看不到 CUSTOMER_PII。如果 SHOW TABLES 返回空或报错,通常需要依次检查:共享是否已 ADD ACCOUNT、数据库与架构的 USAGE 是否都已授予、双方区域与云平台是否一致。这三项检查正好对应前面讲的账户边界、对象边界和区域边界。
六、小结:把对象放回边界中理解
Snowflake 共享架构可以概括为:账户是授权主体,区域与云平台是物理边界,数据库、架构、表是内容边界,Share 是承载授权清单的逻辑容器,消费方通过只读数据库获得结构对齐的访问视图。理解这些对象各自的位置与边界,才能在后续设计共享方案时准确判断“该共享什么、共享给谁、对方能看到什么、什么时候会失效”。