Snowflake 快速入门——安全数据共享

121 阅读12分钟

在当今互联的世界里,安全而高效的数据共享对现代企业至关重要。能在组织内部与外部无缝交换数据,将为协作、创新与基于数据的决策带来巨大的机会。然而,传统的数据共享方式常常面临诸多挑战:传输繁琐、存在安全风险、且需要在多套系统间费力维护数据一致性。

本章将深入探讨安全数据共享,介绍 Snowflake 提供的一系列创新特性,这些特性通过在同一地区(region)内不同账户之间实现安全且无缝的数据交换,重塑数据共享的格局。我们将系统解构 Snowflake 的数据共享能力,帮助你掌握利用这项变革性技术所需的知识与工具。

本章涵盖以下要点:

  • Snowflake 数据共享的优势:首先剖析使用 Snowflake 进行数据共享的吸引力,突出其速度、安全性与灵活性
  • 理解 share 对象:作为 Snowflake 数据共享架构的核心,我们将阐释 share 对象 在定义权限与授予特定数据库对象访问中的作用。
  • 实施安全的表共享:提供分步指南,演示如何在 Snowflake 中安全共享表,包括创建 share 对象、授权以及访问共享数据。
  • 借助安全视图实现精细化控制:安全视图为数据提供方带来细粒度的共享控制。本章将说明如何创建安全视图,并用其实现行级访问控制

读完本章后,你将对 Snowflake 的安全数据共享功能有扎实的理解,并能运用这些能力促进无缝协作,释放数据资产的全部潜能。

Snowflake 数据共享的优势(Benefits of Snowflake Data Sharing)

Snowflake 的数据共享能力为传统方法提供了强有力的替代方案,带来多项关键收益:

  • 无数据移动、无数据复制:首要优势是无需移动或复制数据。传统共享常依赖 ETL,导致数据重复不一致风险。Snowflake 的方式允许消费者直接在提供方环境访问共享数据,不进行物理传输,从而避免复杂性。
  • 即时访问最新数据:这种模式不仅简化流程,还保证消费者始终访问到最新信息——提供方的更新会即时反映给消费者。
  • 安全性:相较于 FTP、邮件等方式存在的安全隐患,Snowflake 的安全数据共享模型允许提供方对特定对象授予受限访问,例如安全视图用户自定义函数(UDF)
  • 访问控制安全视图在实现行级访问控制方面至关重要,确保消费者只能看到被授权的数据。这种对可见性的细粒度控制提升了安全性并保护敏感信息。

认识 Share 对象(Understanding Share Objects)

在了解了 Snowflake 数据共享的诸多优势后,我们来看看促成这种无缝且安全交换的机制——share 对象。它是 Snowflake 数据共享架构的核心,决定了在同一区域(region)内不同 Snowflake 账户之间如何共享与访问数据

需要明确的是:在共享过程中并没有真实的数据复制。因此,数据消费者只为计算付费不为存储付费,因为数据物理上仍存放在提供方。由于信息并未实际传输,当提供方更新数据时,消费者可即时获得更新。同一个数据提供方可以同时面向公司内外的多个消费者;同样,某个消费者也可以访问多个提供方,从而形成供给方—消费方网络

Snowflake 的数据共享功能通过特定的 share 对象,在同一区域内的账户之间共享数据库对象,这些对象可以是安全视图安全 UDF 等。数据提供方首先创建一个 share 对象(具名的 Snowflake 对象),其中封装了在提供方与消费者间共享所需的信息,例如:

  • 允许访问提供方数据库及所选对象的权限
  • 消费者数据库以及被共享的对象等。

需要注意:Snowflake 的数据共享仅在 Snowflake 账户之间生效。若希望向外部世界授予访问,需要使用Reader Account(读取者账户) 。提供方账户可以为尚非 Snowflake 客户的消费者创建 Reader Account(见图 5-1)。

image.png

表 5-1 概述了图 5-1 中数据共享流程的步骤(Table 5-1 Data Sharing Process)

步骤说明
1提供方账户在数据库 Provider_DB_1 上创建名为 Share_1share 对象,并为 table_1_1 中选定对象授予访问权限。
2消费方账户基于 Share_1 对象创建只读数据库;此后,所有共享对象对消费者可用。图中账户示例为 Customer Account #1Customer Account #2
3若消费者没有 Snowflake 账户,提供方可为其创建 Reader Account(读取者账户) 。在图 5-x 中,此功能用于 Share_2 对象。
4共享对象可以是(如 table_1_1),但最佳实践是使用安全视图(secure view) ;视图可包含来自多个数据库的私有表。
5安全视图中,可选地按行级控制数据访问;为此需创建映射表,将一组记录与用户进行映射。
6消费方账户按照 RBAC(基于角色的访问控制)授予权限。

更多关于 Reader Account 的信息,见:
docs.snowflake.net/manuals/use…

实施安全的表共享(Implementing Secure Table Sharing)

若你已有一张表,需要按如下步骤组织对该表的访问:

  1. 创建 share 对象
  2. 加入 share 并授予权限。
  3. 消费方账户加入该 share。
  4. 登录消费方账户
  5. 在消费方账户中添加可用的 share,随后即可查询共享表。

创建并共享一张表(CREATE AND SHARE A TABLE)

按每步给出的代码在实际中完成表共享。

1. 登录你的 Snowflake 提供方账户

2. 打开空白工作表并运行以下代码:

-- Create a new database called samples and a schema called finance
use role sysadmin;
create database samples;
create schema samples.finance;

-- Create a table named stocks_data in the samples.finance schema
create or replace table samples.finance.stocks_data (
    id int,
    symbol string,
    date date,
    time time(9),
    bid_price float,
    ask_price float,
    bid_cnt int,
    ask_cnt int
    );

-- Insert values into your stocks_data table.
insert into samples.finance.stocks_data
values(1,'TDC',dateadd(day,  -1,current_date()), '10:15:00', 36.3, 36.0, 10, 10),
 (2,'TDC', dateadd(month,-2,current_date()), '11:14:00', 36.5, 36.2, 10, 10),
 (3,'ORCL', dateadd(day, -1,current_date()), '11:15:00',57.8, 59.9, 13, 13),
 (4,'ORCL', dateadd(month,-2,current_date()), '09:11:00',57.3, 57.9, 12, 12),
 (5,'TSLA', dateadd(day, -1,current_date()), '11:01:00', 255.2, 256.4, 22, 22),
 (6,'TSLA', dateadd(month, -2,current_date()), '11:13:00', 255.2, 255.7, 23, 23);

select * from samples.finance.stocks_data;

image.png

图 5-2 执行第 2 步代码后 samples.finance.stocks_data 的输出

3. 运行如下代码。它会创建一个 share 对象并向一个新账户授予权限。

# Create and show share. Figure 5-3 shows how this displays
use role accountadmin;
create or replace share stocks_share;
show shares;

# Provide permissions on database samples and add to the stocks_share share
grant usage on database samples to share stocks_share;

# Provide permissions to finance schema and add to the stocks_share share
grant usage on schema samples.finance to share stocks_share;

# Provide permissions on stocks_data table and add to the stocks_share share.
grant select on table samples.finance.stocks_data to share stocks_share;

# Display the objects granted to stocks_share. Figure5-4 shows how this should look
show grants to share stocks_share;

# Add consumer access to the stocks_share for the <consumer_account>
alter share stocks_share add accounts=<consumer_account>;

image.png 图 5-3 share 对象的元数据

image.png 图 5-4 share 对象上的授权情况

4.消费方账户中运行如下代码以查看可用的 share:

use role accountadmin;
show shares;
desc share <consumer_account>.STOCKS_SHARE;

image.png

图 5-5 消费方账户中的可用 share

5. 用前几步授权所用的 <consumer_account> 登录,并基于该 share 创建数据库。执行后可在 Snowsight UI 中看到 shared_db(见图 5-6)。

create database shared_db from share <provider_account>.STOCKS_SHARE;

image.png

图 5-6 消费方账户中的可用共享对象

6. 从刚创建的数据库中查询共享表(图 5-7 为结果):

select * from SHARED_DB.Finance.STOCKS_DATA;

image.png

图 5-7 查询共享表后的结果

使用安全视图进行数据共享(Data Sharing Using a Secure View)

在很多场景下,你有一张基表,但只希望部分记录对外可见。最佳实践是使用安全视图(secure view) 。若你已有一张表,可按以下步骤通过安全视图来组织对该表的访问:

6. 如有需要,先给表新增一列,用来将数据划分为有意义的分组以便过滤。
7. 创建一张映射表,用于记录分组名消费者 Snowflake 账户名之间的对应关系。
8. 基于该表创建安全视图
9. 创建一个 share 对象
10.安全视图添加到 share 对象,并授予相应权限
11.消费者的 Snowflake 账户添加到该 share 对象。

(关于“第 1 步”):如果你的表已经有可用于过滤的数据列(例如 region),且你只想共享某些区域的数据,就不需要新增分组列。

使用安全视图共享表(SHARING A TABLE USING A SECURE VIEW)

下面演示如何通过安全视图实现行级共享的访问控制。

1. 登录你的 Snowflake 账户。

2. 切换到 Worksheet,执行以下代码,为 stocks_data添加分组列

/* Add a grouping column to the stocks_data table. */
use role sysadmin;
alter table samples.finance.stocks_data
  add column access_id string;

/* Updating the grouping column with appropriate grouping data based on how you want to share the data. In this example we divided the stock data into two groups, GRP_1 (for sharing with IT companies) and GRP_2 (for sharing with auto companies). */
update finance.stocks_data
    set access_id = 'GRP_1'
where id in (1,2,3,4);

update finance.stocks_data
    set access_id = 'GRP_2'
where id in (5,6);

/* Don′t forget to commit the changes */
commit;

/* See your changes */
select * from samples.finance.stocks_data;

image.png

图 5-8 执行第 2 步后变更的示例输出

3. 创建映射表,跟踪哪个 Snowflake 账户可访问哪个 access_id

# Create a mapping table to track access_id to Snowflake consumer account
use role sysadmin;
create or replace table samples.finance.access_map (
  access_id string,
  account string
);

# add access to tech companies for my account
insert into samples.finance.access_map values('GRP_1', current_account());

# add access to auto companies for my account
insert into samples.finance.access_map values('GRP_2', '<consumer_account>');

commit;
select * from samples.finance.access_map;

4. 创建安全视图并授予权限。这里使用 current_account() 动态识别用户账户:

# Create a new public schema.
create or replace schema samples.public;

# Create a secure view called samples.public.stocks which based on the table and the mapping table.
create or replace secure view samples.public.stocks as
    select sd.symbol, sd.date, sd.time, sd.bid_price, sd.ask_price, sd.bid_cnt, sd.ask_cnt
    from samples.finance.stocks_data sd
    join samples.finance.access_map  am on sd.access_id = am.access_id
     and am.account = current_account();

# Grant the appropriate rights to the view
grant select on samples.public.stocks  to public;

5. 测试表与安全视图的访问:

select count(*) from samples.finance.stocks_data;
select * from samples.finance.stocks_data;

select count(*) from samples.public.stocks;
select * from samples.public.stocks;

select * from samples.public.stocks
where symbol = 'TDC';

6. 通过会话参数模拟数据共享消费者,测试对安全视图的访问:

alter session set simulated_data_sharing_consumer=<consumer_name>;
select * from samples.public.stocks;

image.png

图 5-9 (会话模拟模式下)消费者可见的安全视图数据

7. 创建 share 对象,将安全视图加入并授予权限:

# Return back to the Producer account session
alter session set simulated_data_sharing_consumer='<provider_account>';
use role accountadmin;

# Create new share object called share_sv
create or replace share share_sv;

# Grant privileges to share object, schema, and view
grant usage on database samples to share share_sv;
grant usage on schema samples.public to share share_sv;
grant select on samples.public.stocks to share share_sv;
show grants to share share_sv;

# grant privileges to share with the consumer accounts
alter share share_sv set accounts = <consumer_accounts>;
show shares;

image.png 图 5-10 消费者可见的视图

8.消费者账户中,从 share_sv 创建数据库并授予权限:

# Create a database from the share object called share_sv.
use role accountadmin;
show shares;
create database shared_views_db from share <provider_account>.share_sv;

# Grant import privileges to the share object to sysadmin
grant imported privileges on database shared_views_db to sysadmin;

use role sysadmin;

# check to ensure access has been granted.
show views;

use warehouse <warehouse_name>;
select * from stocks;

image.png

图 5-11 消费者可见的安全视图数据

共享:常规视图 vs. 物化视图

在 Snowflake 中,视图为简化与定制数据访问提供了手段。常规视图(regular view)本质上是一条已保存的查询;它不存储结果集,而是在每次被查询时,对底层基表执行视图中的查询,因此始终反映最新数据。与之相对,物化视图(materialized view)会将查询的结果集以物理表的形式保存。底层基表发生变化时,Snowflake 会自动维护与更新这些预计算数据。

物化视图在处理复杂高频访问的数据时,通常能带来显著更快的查询性能,但由于不是瞬时更新,数据新鲜度可能存在短暂延迟。因此,在两者之间做选择,取决于你的应用需求:在实时性性能之间取得平衡。

:常规视图与物化视图都可以定义为**“安全视图(secure view)” 。安全视图可隐藏底层查询定义**,并防止消费者通过直接查询访问基表。这对于保护敏感数据或知识产权至关重要。

总之,在共享常规视图共享物化视图之间进行选择,应结合性能、数据新鲜度与成本的优先级来决定。理解它们的差异,有助于你更好地利用 Snowflake 的数据共享能力。表 5-2 可帮助判断哪种视图更适合你的场景。

表 5-2 常规视图 vs. 物化视图

特性常规视图(Regular View)物化视图(Materialized View)
共享对象查询定义预计算数据
数据来源提供方的基表(实时查询)提供方侧存储的结果集
性能可能较慢通常更快
数据新鲜度始终最新更新可能有短延迟
成本影响主要为消费者的计算成本提供方的存储与维护成本

小结

本章介绍了 Snowflake 的数据共享功能,它为数据分发提供了简单、快速且安全的途径。你了解了 share 对象,并考察了使用这些功能的若干基本选项。我们还演示了两种共享方式:一种是直接共享表,另一种是通过安全视图实现更高级的共享。