建立授權的檢視表

本文件說明如何在 BigQuery 中建立授權的檢視表。

您可以透過以下方式在 BigQuery 中建立授權的檢視表:

  • 使用 GCP 主控台或傳統 BigQuery 網頁版 UI
  • 使用指令列工具的 bq mk 指令
  • 呼叫 API 方法 tables.insert
  • 提交 CREATE VIEW 資料定義語言 (DDL) 陳述式
  • 使用用戶端程式庫

總覽

為資料集提供資料檢視存取權,又稱為在 BigQuery 中建立授權資料檢視。透過授權的資料檢視,即使不將基礎資料表的存取權授予特定使用者及群組,也可以和他們分享查詢結果。您也可以使用資料檢視的 SQL 查詢限制使用者能夠查詢的資料欄 (欄位)。

資料檢視的建立位置不能和該資料檢視查詢的來源資料位置相同,因為您只能在資料集層級指派存取控制權,如果建立資料檢視的資料集與來源資料相同,您的使用者就會同時取得資料檢視與資料的存取權。

如需建立授權資料檢視的教學課程,請參閱:在 BigQuery 中建立授權資料檢視

所需權限

如要建立授權的檢視表,您必須具備該檢視表所屬資料集的權限,以及提供該檢視表存取權的資料集的權限。

包含檢視表的資料集

BigQuery 會將檢視表視為資料表資源,因此建立檢視表需要的權限和建立資料表相同。您至少要具備 bigquery.tables.create 權限,才能建立檢視表。以下是具有 bigquery.tables.create 權限的預先定義 Cloud IAM 角色:

  • bigquery.dataEditor
  • bigquery.dataOwner
  • bigquery.admin

此外,具備 bigquery.datasets.create 權限的使用者在建立資料集時,會獲得 bigquery.dataOwner 存取權。 bigquery.dataOwner 存取權可讓使用者在資料集中建立檢視表。

如要進一步瞭解 BigQuery 中的 Cloud IAM 角色和權限,請參閱預先定義的角色與權限一文。

提供檢視表存取權的資料集

您至少要具備 bigquery.datasets.updatebigquery.datasets.get 權限,才能更新資料集屬性。以下是具備 bigquery.datasets.updatebigquery.datasets.get 權限的預先定義 Cloud IAM 角色:

  • bigquery.dataOwner
  • bigquery.admin

另外,具備 bigquery.datasets.create 權限的使用者會在建立資料集時獲得 bigquery.dataOwner 存取權限。 bigquery.dataOwner 存取權限可讓使用者在自己建立的資料集中更新屬性。

如要進一步瞭解 BigQuery 中的 Cloud IAM 角色和權限,請參閱存取權控管

將檢視表存取權授予資料集

如何將資料檢視存取權授予資料集:

主控台

  1. 在導覽面板的「Resources」(資源) 區段,展開您的專案並選取資料集。

  2. 按一下視窗右側的 [Share dataset] (分享資料集)

  3. 在「Dataset permissions」(資料集權限) 面板中,選取 [Authorized views] (授權的檢視表) 分頁標籤。

  4. 在「Share authorized view」(分享授權的檢視表) 部分中:

    • 在「Select project」(選取專案) 部分,確認專案名稱。如果資料檢視在其他專案中,請務必選取正確的專案。
    • 在「Select dataset」(選取資料集) 部分,選擇包含目標資料檢視的資料集。
    • 在「Select view」(選取資料檢視) 部分,選取您想要授權的資料檢視。
  5. 按一下 [Add] (新增),然後按一下 [Done] (完成)。

傳統版 UI

  1. 在含有來源資料表的資料集右側,點選下拉式箭頭,然後選擇 [Share Dataset] (分享資料集)。

  2. 在「分享資料集」對話方塊中的「新增使用者」部分,按一下欄位左側的下拉式選單,然後選擇 [授權的資料檢視]

  3. 按一下 [Select View]

  4. 在「選取資料檢視」對話方塊中:

    • 在「專案」的部分確認專案名稱。如果資料檢視在其他專案中,請務必要選取正確的專案。
    • 在「資料集」的部分選擇包含目標資料檢視的資料集。
    • 在「資料表 ID」的部分,為想要授權的資料檢視輸入名稱。
    • 點選 [確定]

      選取授權的檢視表

  5. 按一下 [Add] (新增),然後點選 [Save changes] (儲存變更)

CLI

  1. 使用 show 指令將現有的資料集資訊 (包括存取權控管設定) 寫入 JSON 檔案。如果資料集位於非預設專案中,請使用下列格式將專案 ID 新增至資料集名稱:project_id:dataset

    bq show \
    --format=prettyjson \
    project_id:dataset > path_to_file
    

    其中:

    • 「project_id」是您的專案 ID。
    • 「dataset」是資料集的名稱。
    • 「path_to_file」是本機中 JSON 檔案的路徑。

    範例:

    輸入下列指令,將 mydataset 的存取權控管設定寫入 JSON 檔案。mydataset 位於預設專案。

    bq show --format=prettyjson mydataset > /tmp/mydataset.json
    

    輸入下列指令,將 mydataset 的存取權控管寫入 JSON 檔案。mydataset 位於 myotherproject 中。

    bq show --format=prettyjson \
    myotherproject:mydataset > /tmp/mydataset.json
    
  2. 將授權的檢視表新增至 JSON 檔案的「access」區段。

    例如,資料集的 JSON 檔案的存取權區段會如下所示:

    {
     "access": [
      {
       "role": "READER",
       "specialGroup": "projectReaders"
      },
      {
       "role": "WRITER",
       "specialGroup": "projectWriters"
      },
      {
       "role": "OWNER",
       "specialGroup": "projectOwners"
      }
      {
       "role": "READER",
       "specialGroup": "allAuthenticatedUsers"
      }
      {
       "role": "READER",
       "domain": "[DOMAIN_NAME]"
      }
      {
       "role": "WRITER",
       "userByEmail": "[USER_EMAIL]"
      }
      {
       "role": "READER",
       "groupByEmail": "[GROUP_EMAIL]"
      },
      {
       "view":{
       "datasetId": "[DATASET_NAME]",
       "projectId": "[PROJECT_NAME]",
       "tableId": "[VIEW_NAME]"
       }
      }
     ],
    }
    

  3. 編輯完成之後,請使用 update 指令和 --source 標記加入 JSON 檔案。如果資料集位於非預設專案中,請使用下列格式將專案 ID 新增至資料集名稱:project_id:dataset

    bq update \
    --source path_to_file \
    project_id:dataset
    

    其中:

    • 「path_to_file」是本機中 JSON 檔案的路徑。
    • 「project_id」是您的專案 ID。
    • 「dataset」是資料集的名稱。

    範例:

    輸入下列指令,更新 mydataset 的存取權控管。mydataset 位於預設專案中。

     bq update --source /tmp/mydataset.json mydataset
    

    輸入下列指令來更新 mydataset 的存取權控管設定。mydataset 位於 myotherproject

     bq update --source /tmp/mydataset.json myotherproject:mydataset
    
  4. 如要驗證您的存取權控管設定變更,請再次輸入 show 指令,而不要將資訊寫入檔案。

    bq show --format=prettyjson [DATASET]
    

    bq show --format=prettyjson [PROJECT_ID]:[DATASET]
    

API

呼叫 datasets.patch 並使用 access 屬性來更新存取權控管。詳情請參閱資料集一文。

因為 datasets.update 方法會取代整個資料集資源,因此更新存取控制權時建議使用 datasets.patch 方法。

Go

在試行這個範例之前,請按照 BigQuery 快速入門導覽課程:使用用戶端程式庫中的 Go 相關設定指示操作。詳情請參閱 BigQuery Go API 參考說明文件

// To run this sample, you will need to create (or reuse) a context and
// an instance of the bigquery client.  For example:
// import "cloud.google.com/go/bigquery"
// ctx := context.Background()
// client, err := bigquery.NewClient(ctx, "your-project-id")
srcDataset := client.Dataset(srcDatasetID)
viewDataset := client.Dataset(viewDatasetID)
view := viewDataset.Table(viewID)

// First, we'll add a group to the ACL for the dataset containing the view.  This will allow users within
// that group to query the view, but they must have direct access to any tables referenced by the view.
vMeta, err := viewDataset.Metadata(ctx)
if err != nil {
	return err
}
vUpdateMeta := bigquery.DatasetMetadataToUpdate{
	Access: append(vMeta.Access, &bigquery.AccessEntry{
		Role:       bigquery.ReaderRole,
		EntityType: bigquery.GroupEmailEntity,
		Entity:     "example-analyst-group@google.com",
	}),
}
if _, err := viewDataset.Update(ctx, vUpdateMeta, vMeta.ETag); err != nil {
	return err
}

// Now, we'll authorize a specific view against a source dataset, delegating access enforcement.
// Once this has been completed, members of the group previously added to the view dataset's ACL
// no longer require access to the source dataset to successfully query the view.
srcMeta, err := srcDataset.Metadata(ctx)
if err != nil {
	return err
}
srcUpdateMeta := bigquery.DatasetMetadataToUpdate{
	Access: append(srcMeta.Access, &bigquery.AccessEntry{
		EntityType: bigquery.ViewEntity,
		View:       view,
	}),
}
if _, err := srcDataset.Update(ctx, srcUpdateMeta, srcMeta.ETag); err != nil {
	return err
}

Python

在嘗試此範例之前,請至 BigQuery 快速入門導覽課程:使用用戶端程式庫,按照 Python 設定說明進行操作。詳情請參閱 BigQuery Python API 參考說明文件

# from google.cloud import bigquery
# client = bigquery.Client()

# Assign access controls to the dataset containing the view
# shared_dataset_id = 'my_shared_dataset'
# analyst_group_email = 'data_analysts@example.com'
shared_dataset = client.get_dataset(
    client.dataset(shared_dataset_id)
)  # API request
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
# project = 'my-project'
# source_dataset_id = 'my_source_dataset'
source_dataset = client.get_dataset(
    client.dataset(source_dataset_id)
)  # API request
view_reference = {
    "projectId": project,
    "datasetId": shared_dataset_id,
    "tableId": "my_shared_view",
}
access_entries = source_dataset.access_entries
access_entries.append(bigquery.AccessEntry(None, "view", view_reference))
source_dataset.access_entries = access_entries
source_dataset = client.update_dataset(
    source_dataset, ["access_entries"]
)  # API request

使用資料檢視強制執行資料列層級存取權

資料檢視可以用於限制特定資料欄 (欄位) 的存取權。如果想要限制使用者或群組只能存取資料表上的個別資料列,您不需要為他們另外建立獨立的資料檢視,可以改為使用 SESSION_USER() 函式傳會目前使用者的電子郵件地址。

如要對不同的使用者顯示不同的資料列,您可以在資料表中加入另一個欄位,並在其中列出您要允許查看該資料列的使用者,然後再建立一個使用 SESSION_USER() 函式的資料檢視。在以下範例中,使用者的名稱儲存在 allowed_viewer 欄位中:

SELECT
  COLUMN_1,
  COLUMN_2
FROM
  `dataset.view`
WHERE
  allowed_viewer = SESSION_USER()

這種方法的缺點是,您一次只能將存取權授予一位使用者。如要解決這個問題,您可以把 allowed_viewer 變成重複欄位,這樣一來就可以為每一個資料列提供一份使用者清單。但是即使使用了重複欄位,將使用者名稱儲存在資料表後,您還是必須手動追蹤擁有各資料列存取權的個別使用者。

或者您也可以在 allowed_viewer 欄位中填入群組名稱,然後建立一個獨立的資料表,將群組對應至使用者。將群組對應至使用者的資料表會有一個儲存群組名稱和使用者名稱的結構定義,例如:{group:string, user_name:string}。使用這種方法,您就可以透過含有所需資料的資料表分別管理使用者和群組資訊。

如果對應資料表的名稱是 private.access_control,用於建立授權資料檢視的 SQL 查詢就會如下所示:

SELECT
  c.customer,
  c.id
FROM
  `private.customers` c
INNER JOIN (
  SELECT
    group
  FROM
    `private.access_control`
  WHERE
    SESSION_USER() = user_name) g
ON
  c.allowed_group = g.group

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
需要協助嗎?請前往我們的支援網頁