创建授权视图


BigQuery 是一个 PB 级的分析数据仓库,可用于对大量数据近乎实时地运行 SQL 查询。

在 BigQuery 中,为视图授予数据集访问权限也称为创建已获授权的视图。已获授权的视图可让您与特定用户和群组共享查询结果,而无需为其授予底层表的访问权限。您还可以使用视图的 SQL 查询来限制用户可查询的列(字段)。在本教程中,您将创建一个已获授权的视图。

目标

本教程介绍如何完成以下任务:

  • 创建数据集并对其应用访问权限控制
  • 向项目分配访问权限控制
  • 创建一个已获授权的视图,它用于限制用户可查询的数据

费用

BigQuery 是一款付费产品,本教程中涉及的操作将产生 BigQuery 使用费。BigQuery 提供一些有特定限额的免费资源。如需了解详情,请参阅 BigQuery 免费操作和免费层级

准备工作

开始学习本教程前,请先使用 Google Cloud Console 创建或选择项目。

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  3. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  4. 新项目会自动启用 BigQuery。如需在预先存在的项目中激活 BigQuery,请转到

    启用 BigQuery API。

    启用 API

  5. 可选:为项目启用结算功能。如果您不想启用结算功能或提供信用卡,本文档中的步骤仍然有效。BigQuery 提供执行这些步骤的沙盒。如需了解详情,请参阅启用 BigQuery 沙盒

创建源数据集

首先,创建一个数据集来存储源数据。在本教程中,您将通过查询 GitHub 公开数据集填充源数据集中的表。源数据集中的数据包含您不希望数据分析师看到的信息。因此,您使用已获授权的视图来限制对数据的访问。

要创建源数据集,请执行以下操作:

控制台

  1. 在 Google Cloud 控制台中,打开 BigQuery 页面。

    转到 BigQuery

  2. 探索器窗格中,选择您要在其中创建数据集的项目。

  3. 展开 操作选项,然后点击创建数据集

  4. 数据集 ID 部分,输入 github_source_data

  5. 保留其他默认设置,然后点击创建数据集

SQL

使用 CREATE SCHEMA DDL 语句

  1. 在 Google Cloud 控制台中,转到 BigQuery 页面。

    转到 BigQuery

  2. 在查询编辑器中,输入以下语句:

    CREATE SCHEMA github_source_data;
    

  3. 点击 运行

如需详细了解如何运行查询,请参阅运行交互式查询

Java

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Java 设置说明进行操作。如需了解详情,请参阅 BigQuery Java API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

// Create a source dataset to store your table.
Dataset sourceDataset = bigquery.create(DatasetInfo.of(sourceDatasetId));

Python

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

from google.cloud import bigquery

client = bigquery.Client()
source_dataset_id = "github_source_data"
source_dataset_id_full = "{}.{}".format(client.project, source_dataset_id)

source_dataset = bigquery.Dataset(source_dataset_id_full)
# Specify the geographic location where the dataset should reside.
source_dataset.location = "US"
source_dataset = client.create_dataset(source_dataset)  # API request

创建源数据集后,您可以使用 SQL 查询在其中填充表。此查询会从 GitHub 公开数据集中检索数据。

控制台

  1. 在 Google Cloud 控制台中,打开 BigQuery 页面。

    转到 BigQuery

  2. 将以下查询复制并粘贴到编辑器窗格中。

    SELECT
      commit,
      author,
      committer,
      repo_name
    FROM
      `bigquery-public-data.github_repos.commits`
    LIMIT
      1000;
    
  3. 点击更多,然后选择查询设置

  4. 目标位置部分中,选择为查询结果设置目标表

  5. 对于数据集,请输入 PROJECT_ID.github_source_data。请将 PROJECT_ID 替换为您的项目 ID。

  6. 对于表 ID,输入 github_contributors

  7. 点击保存

  8. 点击运行

  9. 完成查询后,点击 github_contributors,然后点击预览,验证数据是否已写入表中。

Java

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Java 设置说明进行操作。如需了解详情,请参阅 BigQuery Java API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

// Populate a source table
String tableQuery =
    "SELECT commit, author, committer, repo_name"
        + " FROM `bigquery-public-data.github_repos.commits`"
        + " LIMIT 1000";
QueryJobConfiguration queryConfig =
    QueryJobConfiguration.newBuilder(tableQuery)
        .setDestinationTable(TableId.of(sourceDatasetId, sourceTableId))
        .build();
bigquery.query(queryConfig);

Python

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

source_table_id = "github_contributors"
job_config = bigquery.QueryJobConfig()
job_config.destination = source_dataset.table(source_table_id)
sql = """
    SELECT commit, author, committer, repo_name
    FROM `bigquery-public-data.github_repos.commits`
    LIMIT 1000
"""
query_job = client.query(
    sql,
    # Location must match that of the dataset(s) referenced in the query
    # and of the destination table.
    location="US",
    job_config=job_config,
)  # API request - starts the query

query_job.result()  # Waits for the query to finish

创建用于存储视图的数据集

创建源数据集后,您需要创建一个新的独立数据集,以存储要与数据分析师共享的授权视图。在稍后的步骤中,您将向授权视图授予对源数据集内数据的访问权限。您的数据分析师将有权访问已获授权的视图,但无权直接访问源数据。

已获授权的视图应在与源数据不同的数据集中创建。这样,数据所有者可以为用户提供对已授权的视图的访问权限,而无需同时授予对底层数据的访问权限。源数据数据集和已获授权的视图数据集必须位于同一地区位置

要创建用于存储视图的数据集,请执行以下操作:

控制台

  1. 在 Google Cloud 控制台中,打开 BigQuery 页面。

    转到 BigQuery

  2. 探索器面板中,选择您要在其中创建数据集的项目。

  3. 展开 操作选项,然后点击创建数据集

  4. 数据集 ID 部分,输入 shared_views

  5. 保留其他默认设置,然后点击创建数据集

SQL

使用 CREATE SCHEMA DDL 语句

  1. 在 Google Cloud 控制台中,转到 BigQuery 页面。

    转到 BigQuery

  2. 在查询编辑器中,输入以下语句:

    CREATE SCHEMA shared_views;
    

  3. 点击 运行

如需详细了解如何运行查询,请参阅运行交互式查询

Java

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Java 设置说明进行操作。如需了解详情,请参阅 BigQuery Java API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

// Create a separate dataset to store your view
Dataset sharedDataset = bigquery.create(DatasetInfo.of(sharedDatasetId));

Python

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

shared_dataset_id = "shared_views"
shared_dataset_id_full = "{}.{}".format(client.project, shared_dataset_id)

shared_dataset = bigquery.Dataset(shared_dataset_id_full)
shared_dataset.location = "US"
shared_dataset = client.create_dataset(shared_dataset)  # API request

在新数据集中创建视图

在新数据集中,您可以创建想要授权的视图,即您与数据分析师共享的视图。该视图是使用 SQL 查询创建的,其中未包含您不希望数据分析师看到的列。

在本教程中,您的共享视图不包含除作者姓名以外的作者信息,且不包含除提交者姓名以外的提交者信息。

要在新数据集中创建视图,请执行以下操作:

控制台

  1. 在 Google Cloud 控制台中,打开 BigQuery 页面。

    转到 BigQuery

  2. 将以下查询复制并粘贴到编辑器窗格中。请将 PROJECT_ID 替换为您的项目 ID。

    SELECT
      commit,
      author.name AS author,
      committer.name AS committer,
      repo_name
    FROM
      `PROJECT_ID.github_source_data.github_contributors`;
    
  3. 点击保存 > 保存视图

  4. 保存视图对话框中,执行以下操作:

    1. Project 部分中,验证是否已选定您的项目。
    2. 对于数据集,输入 shared_views
    3. 对于,输入 github_analyst_view
    4. 点击保存

SQL

使用 CREATE VIEW DDL 语句

  1. 在 Google Cloud 控制台中,转到 BigQuery 页面。

    转到 BigQuery

  2. 在查询编辑器中,输入以下语句:

    CREATE VIEW shared_views.github_analyst_view
    AS (
      SELECT
        commit,
        author.name AS author,
        committer.name AS committer,
        repo_name
      FROM
        `PROJECT_ID.github_source_data.github_contributors`
    );
    

    PROJECT_ID 替换为您的项目 ID。

  3. 点击 运行

如需详细了解如何运行查询,请参阅运行交互式查询

Java

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Java 设置说明进行操作。如需了解详情,请参阅 BigQuery Java API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

// Create the view in the new dataset
String viewQuery =
    String.format(
        "SELECT commit, author.name as author, committer.name as committer, repo_name FROM %s.%s.%s",
        projectId, sourceDatasetId, sourceTableId);

ViewDefinition viewDefinition = ViewDefinition.of(viewQuery);

Table view =
    bigquery.create(TableInfo.of(TableId.of(sharedDatasetId, sharedViewId), viewDefinition));

Python

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

shared_view_id = "github_analyst_view"
view = bigquery.Table(shared_dataset.table(shared_view_id))
sql_template = """
    SELECT
        commit, author.name as author,
        committer.name as committer, repo_name
    FROM
        `{}.{}.{}`
"""
view.view_query = sql_template.format(
    client.project, source_dataset_id, source_table_id
)
view = client.create_table(view)  # API request

向数据分析师分配项目级 IAM 角色

为了查询视图,您的数据分析师需要具有运行查询作业的权限。bigquery.user 角色具有在项目中运行作业(包括查询作业)的权限。如果您向用户或群组授予项目级层的 bigquery.user 角色,则用户可创建数据集,并可针对这些数据集中的表运行查询作业。bigquery.user 角色不针对用户尚未创建的数据集授予用户查询数据、查看表数据或查看表架构详细信息的权限。

向数据分析师分配项目级层的 bigquery.user 角色后,他们也无法查看或查询包含视图所查询的表的数据集中的表数据。bigquery.user 角色也不会授予用户更新视图的权限。应向企业中的大多数人(数据科学家、商业智能分析师和数据分析师)分配项目级层的 bigquery.user 角色。

当您将群组添加到 IAM 角色时,电子邮件地址和网域必须与某个有效的 Google 账号或 Google Apps 账号相关联。

如需将数据分析师群组分配给项目级层的 bigquery.user 角色,请执行以下操作:

控制台

  1. 在 Google Cloud Console 中打开 IAM 网页。

    打开 IAM 页面

  2. 确保在顶部栏的项目选择器中选择您的项目。

  3. 点击 授予访问权限

  4. 授予对以下内容的访问权限对话框中:

    1. 新的主账号框中,输入包含数据分析师的群组,例如 data_analysts@example.com
    2. 选择角色框中,搜索 BigQuery User 角色并将其选中。
    3. 点击保存

向包含视图的数据集分配访问权限控制

为了让数据分析师能够查询视图,需要针对包含该视图的数据集向他们授予 bigquery.dataViewer 角色。bigquery.user 角色为您的数据分析师提供创建查询作业所需的权限。但是,他们无法成功查询视图,除非他们还拥有对包含该视图的数据集的 bigquery.dataViewer 访问权限。

要向数据分析师提供对数据集的 bigquery.dataViewer 访问权限,请执行以下操作:

控制台

  1. 在 Google Cloud 控制台中,打开 BigQuery 页面。

    转到 BigQuery

  2. 浏览器窗格中,选择 shared_views 数据集。

  3. 点击 共享 > 权限

  4. 数据集权限窗格中,点击添加主账号

  5. 新的主账号框中,输入包含数据分析师的群组(例如 data_analysts@example.com)。

  6. 点击选择角色,然后选择 BigQuery > BigQuery Data Viewer

  7. 点击保存

  8. 点击关闭

Java

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Java 设置说明进行操作。如需了解详情,请参阅 BigQuery Java API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

// Assign access controls to the dataset containing the view
List<Acl> viewAcl = new ArrayList<>(sharedDataset.getAcl());
viewAcl.add(Acl.of(new Acl.Group("example-analyst-group@google.com"), Acl.Role.READER));
sharedDataset.toBuilder().setAcl(viewAcl).build().update();

Python

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

# analyst_group_email = 'data_analysts@example.com'
access_entries = shared_dataset.access_entries
access_entries.append(
    bigquery.AccessEntry("READER", "groupByEmail", analyst_group_email)
)
shared_dataset.access_entries = access_entries
shared_dataset = client.update_dataset(
    shared_dataset, ["access_entries"]
)  # API request

向视图授予访问源数据集的权限

当您为包含视图的数据集创建访问权限控制后,会将视图添加为源数据集中已获授权的视图。此授权为视图(而非数据分析师群组)提供源数据的访问权限。

要向视图授予访问源数据的权限,请执行以下操作:

控制台

  1. 在 Google Cloud 控制台中,打开 BigQuery 页面。

    转到 BigQuery

  2. 浏览器窗格中,选择 github_source_data 数据集。

  3. 点击 共享,然后选择向视图授权

  4. 在打开的已获授权的视图窗格的已获授权的视图字段中,输入 github_analyst_view 视图。

  5. 点击添加授权

github_analyst_view 视图现在有权访问源数据集中的数据。

Java

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Java 设置说明进行操作。如需了解详情,请参阅 BigQuery Java API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

// Authorize the view to access the source dataset
List<Acl> srcAcl = new ArrayList<>(sourceDataset.getAcl());
srcAcl.add(Acl.of(new Acl.View(view.getTableId())));
sourceDataset.toBuilder().setAcl(srcAcl).build().update();

Python

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

access_entries = source_dataset.access_entries
access_entries.append(
    bigquery.AccessEntry(None, "view", view.reference.to_api_repr())
)
source_dataset.access_entries = access_entries
source_dataset = client.update_dataset(
    source_dataset, ["access_entries"]
)  # API request

验证配置

配置完成后,数据分析师群组(例如 data_analysts)的成员可以通过查询视图来验证配置。

要验证配置,请执行以下操作:

SQL

让数据分析师群组的成员执行以下操作:

  1. 在 Google Cloud 控制台中,转到 BigQuery 页面。

    转到 BigQuery

  2. 在查询编辑器中,输入以下语句:

    SELECT
      *
    FROM
      `PROJECT_ID.shared_views.github_analyst_view`;
    

    PROJECT_ID 替换为您的项目 ID。

  3. 点击 运行

如需详细了解如何运行查询,请参阅运行交互式查询

完整源代码

下面是本教程的完整源代码,供您参考。

Java

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Java 设置说明进行操作。如需了解详情,请参阅 BigQuery Java API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

// Create a source dataset to store your table.
Dataset sourceDataset = bigquery.create(DatasetInfo.of(sourceDatasetId));

// Populate a source table
String tableQuery =
    "SELECT commit, author, committer, repo_name"
        + " FROM `bigquery-public-data.github_repos.commits`"
        + " LIMIT 1000";
QueryJobConfiguration queryConfig =
    QueryJobConfiguration.newBuilder(tableQuery)
        .setDestinationTable(TableId.of(sourceDatasetId, sourceTableId))
        .build();
bigquery.query(queryConfig);

// Create a separate dataset to store your view
Dataset sharedDataset = bigquery.create(DatasetInfo.of(sharedDatasetId));

// Create the view in the new dataset
String viewQuery =
    String.format(
        "SELECT commit, author.name as author, committer.name as committer, repo_name FROM %s.%s.%s",
        projectId, sourceDatasetId, sourceTableId);

ViewDefinition viewDefinition = ViewDefinition.of(viewQuery);

Table view =
    bigquery.create(TableInfo.of(TableId.of(sharedDatasetId, sharedViewId), viewDefinition));

// Assign access controls to the dataset containing the view
List<Acl> viewAcl = new ArrayList<>(sharedDataset.getAcl());
viewAcl.add(Acl.of(new Acl.Group("example-analyst-group@google.com"), Acl.Role.READER));
sharedDataset.toBuilder().setAcl(viewAcl).build().update();

// Authorize the view to access the source dataset
List<Acl> srcAcl = new ArrayList<>(sourceDataset.getAcl());
srcAcl.add(Acl.of(new Acl.View(view.getTableId())));
sourceDataset.toBuilder().setAcl(srcAcl).build().update();

Python

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

# Create a source dataset
from google.cloud import bigquery

client = bigquery.Client()
source_dataset_id = "github_source_data"
source_dataset_id_full = "{}.{}".format(client.project, source_dataset_id)

source_dataset = bigquery.Dataset(source_dataset_id_full)
# Specify the geographic location where the dataset should reside.
source_dataset.location = "US"
source_dataset = client.create_dataset(source_dataset)  # API request

# Populate a source table
source_table_id = "github_contributors"
job_config = bigquery.QueryJobConfig()
job_config.destination = source_dataset.table(source_table_id)
sql = """
    SELECT commit, author, committer, repo_name
    FROM `bigquery-public-data.github_repos.commits`
    LIMIT 1000
"""
query_job = client.query(
    sql,
    # Location must match that of the dataset(s) referenced in the query
    # and of the destination table.
    location="US",
    job_config=job_config,
)  # API request - starts the query

query_job.result()  # Waits for the query to finish

# Create a separate dataset to store your view
shared_dataset_id = "shared_views"
shared_dataset_id_full = "{}.{}".format(client.project, shared_dataset_id)

shared_dataset = bigquery.Dataset(shared_dataset_id_full)
shared_dataset.location = "US"
shared_dataset = client.create_dataset(shared_dataset)  # API request

# Create the view in the new dataset
shared_view_id = "github_analyst_view"
view = bigquery.Table(shared_dataset.table(shared_view_id))
sql_template = """
    SELECT
        commit, author.name as author,
        committer.name as committer, repo_name
    FROM
        `{}.{}.{}`
"""
view.view_query = sql_template.format(
    client.project, source_dataset_id, source_table_id
)
view = client.create_table(view)  # API request

# Assign access controls to the dataset containing the view
# analyst_group_email = 'data_analysts@example.com'
access_entries = shared_dataset.access_entries
access_entries.append(
    bigquery.AccessEntry("READER", "groupByEmail", analyst_group_email)
)
shared_dataset.access_entries = access_entries
shared_dataset = client.update_dataset(
    shared_dataset, ["access_entries"]
)  # API request

# Authorize the view to access the source dataset
access_entries = source_dataset.access_entries
access_entries.append(
    bigquery.AccessEntry(None, "view", view.reference.to_api_repr())
)
source_dataset.access_entries = access_entries
source_dataset = client.update_dataset(
    source_dataset, ["access_entries"]
)  # API request

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤