建立及使用叢集資料表

本文件說明如何在 BigQuery 中建立及使用叢集資料表。如需 BigQuery 中的叢集資料表支援總覽,請參閱叢集資料表簡介

建立叢集資料表

您可以使用下列方法建立叢集資料表:

資料表命名

在 BigQuery 中建立資料表時,每個資料集裡的資料表名稱不得重複。資料表名稱可以:

  • 包含的字元總計最多 1,024 個 UTF-8 位元組。
  • 包含類別 L (字母)、M (標記)、N (數字)、Pc (連接符,包括底線)、Pd (破折號)、Zs (空格) 的 Unicode 字元。詳情請參閱一般類別

以下都是有效的資料表名稱範例:table 01ग्राहक00_お客様étudiant-01

注意事項:

  • 根據預設,資料表名稱會區分大小寫。mytableMyTable 可以共存在同一個資料集中,除非是已關閉大小寫區分功能的資料集
  • 部分資料表名稱和資料表名稱前置字串已保留。如果收到錯誤訊息,指出資料表名稱或前置字元已保留,請選取其他名稱,然後再試一次。
  • 如果您在序列中加入多個點運算子 (.),系統會自動移除重複的運算子。

    例如: project_name....dataset_name..table_name

    變成這樣: project_name.dataset_name.table_name

所需權限

如要建立資料表,您必須具備下列 IAM 權限:

  • bigquery.tables.create
  • bigquery.tables.updateData
  • bigquery.jobs.create

此外,您可能需要 bigquery.tables.getData 權限,才能存取寫入資料表的資料。

下列每個預先定義的 IAM 角色都包含建立資料表所需的權限:

  • roles/bigquery.dataEditor
  • roles/bigquery.dataOwner
  • roles/bigquery.admin (包括 bigquery.jobs.create 權限)
  • roles/bigquery.user (包括 bigquery.jobs.create 權限)
  • roles/bigquery.jobUser (包括 bigquery.jobs.create 權限)

此外,如果您具備 bigquery.datasets.create 權限,就能在自己建立的資料集中建立及更新資料表。

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

透過結構定義建立空白叢集資料表

您在 BigQuery 中建立資料表時,應指定要叢集的欄位。資料表建立完成後,您可以修改叢集資料欄;詳情請參閱「修改叢集規格」。

叢集資料欄必須是頂層的非重複資料欄,且屬於下列任一項資料類型:

  • BIGNUMERIC
  • BOOL
  • DATE
  • DATETIME
  • GEOGRAPHY
  • INT64
  • NUMERIC
  • RANGE
  • STRING
  • TIMESTAMP

您最多可指定四個叢集資料欄,當您指定多個叢集資料欄時,資料欄的順序將決定資料的排序方式。舉例來說,如果資料表是依資料欄 a、b、c 來進行叢集,則資料也會按照相同順序排序,即第一順位是資料欄 a、第二順位是資料欄 b、第三順位是資料欄 c。按照最佳做法,最常用以進行資料篩選或匯總的資料欄應排在第一順位。

叢集資料欄順序亦會影響資料查詢的效能與定價。如要瞭解查詢叢集資料表的最佳做法,請參閱查詢叢集資料表一文。

如何使用結構定義建立空白叢集資料表:

主控台

  1. 前往 Google Cloud 控制台的「BigQuery」頁面。

    前往 BigQuery

  2. 在「Explorer」窗格中展開專案,然後選取資料集。
  3. 在「資料集資訊」部分中,按一下 「建立資料表」
  4. 在「建立資料表」面板中,指定下列詳細資料:
    1. 在「來源」部分,從「使用下列資料建立資料表」清單中選取「空白資料表」
    2. 在「目的地」部分,指定下列詳細資料:
      1. 在「Dataset」(資料集) 部分,選取要建立資料表的資料集。
      2. 在「Table」(資料表) 欄位中,輸入要建立的資料表名稱。
      3. 確認「Table type」(資料表類型) 欄位已設為「Native table」(原生資料表)。
    3. 在「Schema」(結構定義) 區段中,輸入結構定義。 你可以使用下列其中一種方法,手動輸入結構定義資訊:
      • 選項 1:按一下「以文字形式編輯」,然後以 JSON 陣列的形式貼上結構定義。如果您使用 JSON 陣列,可透過與建立 JSON 結構定義檔一樣的程序產生結構定義。您可以輸入下列指令,查看現有資料表的 JSON 格式結構定義:
            bq show --format=prettyjson dataset.table
            
      • 選項 2:按一下 「新增欄位」,然後輸入表格結構定義。指定每個欄位的「Name」(名稱)、「Type」(類型) 和「Mode」(模式)
    4. 針對「Clustering order」(分群順序),輸入一到四個以半形逗號分隔的欄位名稱。
    5. 選用步驟:如要使用客戶管理的加密金鑰,請在「Advanced options」(進階選項) 部分選取「Use a customer-managed encryption key (CMEK)」(使用客戶管理的加密金鑰 (CMEK)) 選項。根據預設,BigQuery 會使用 Google-owned and Google-managed encryption key加密靜態儲存的客戶內容
    6. 點選「建立資料表」。

SQL

使用 CREATE TABLE DDL 陳述式指令,並加上 CLUSTER BY 選項。下列範例會在 mydataset 中建立名為 myclusteredtable 的叢集資料表:

  1. 前往 Google Cloud 控制台的「BigQuery」頁面。

    前往 BigQuery

  2. 在查詢編輯器中輸入下列陳述式:

    CREATE TABLE mydataset.myclusteredtable
    (
      customer_id STRING,
      transaction_amount NUMERIC
    )
    CLUSTER BY
      customer_id
      OPTIONS (
        description = 'a table clustered by customer_id');

  3. 按一下「執行」

如要進一步瞭解如何執行查詢,請參閱「執行互動式查詢」。

bq

使用加上以下旗標的 bq mk 指令:

  • --table (或 -t 捷徑)。
  • --schema。您可利用內嵌方式或以 JSON 結構定義檔提供資料表結構定義。
  • --clustering_fields。您最多可指定四個叢集資料欄。

可選用的參數包括 --expiration--description--time_partitioning_type--time_partitioning_field--time_partitioning_expiration--destination_kms_key--label

如要建立非預設專案中的資料表,請使用下列格式將專案 ID 新增至資料集:project_id:dataset

本文不示範 --destination_kms_key。如要進一步瞭解如何使用 --destination_kms_key,請參閱客戶管理的加密金鑰說明。

輸入下列指令,建立含有結構定義的空白叢集資料表:

bq mk \
    --table \
    --expiration INTEGER1 \
    --schema SCHEMA \
    --clustering_fields CLUSTER_COLUMNS \
    --description "DESCRIPTION" \
    --label KEY:VALUE,KEY:VALUE \
    PROJECT_ID:DATASET.TABLE

更改下列內容:

  • INTEGER1:資料表的預設生命週期 (以秒為單位)。最小值是 3,600 秒 (1 小時)。到期時間為目前世界標準時間加整數值。如果您在建立資料表時設定了資料表到期時間,系統會忽略資料集的預設資料表到期時間設定。設定這個值會在指定時間到期後刪除資料表。
  • SCHEMA:格式為 COLUMN:DATA_TYPE,COLUMN:DATA_TYPE 的內嵌結構定義,或您本機電腦上的 JSON 結構定義檔案路徑。
  • CLUSTER_COLUMNS:以逗號分隔的清單,最多包含四個叢集資料欄。清單不得包含任何空格。
  • DESCRIPTION:置於括號中的資料表說明。
  • KEY:VALUE:代表標籤的鍵/值組合。您可以用逗號分隔的清單輸入多個標籤。
  • PROJECT_ID:您的專案 ID。
  • DATASET:專案中的資料集。
  • TABLE:您要建立的資料表名稱。

您在指令列中指定結構定義時,無法加入 RECORD (STRUCT) 類型和資料欄說明,也不能指定資料欄模式。所有模式均預設為 NULLABLE。如要加入說明、模式和 RECORD 類型,請改為提供 JSON 結構定義檔

範例:

輸入下列指令,在預設專案中的 mydataset 內建立名為 myclusteredtable 的叢集資料表,資料表到期時間設為 2,592,000 秒 (1 個月 30 天)、說明設為 This is my clustered table,而標籤則設為 organization:development。此指令使用 -t 捷徑,而非 --table

結構定義以內嵌方式指定為:timestamp:timestamp,customer_id:string,transaction_amount:float。所指定的叢集欄位 customer_id 用於叢集資料表。

bq mk \
    -t \
    --expiration 2592000 \
    --schema 'timestamp:timestamp,customer_id:string,transaction_amount:float' \
    --clustering_fields customer_id \
    --description "This is my clustered table" \
    --label org:dev \
    mydataset.myclusteredtable

輸入下列指令,在 myotherproject (而非預設專案) 中建立名為 myclusteredtable 的叢集資料表,說明設為 This is my clustered table,標籤則設為 organization:development。此指令使用 -t 捷徑,而非 --table。這個指令不會指定資料表到期時間。如果資料集有預設資料表到期時間,系統會直接套用這個時間。如果資料集沒有預設資料表到期時間,資料表將永不過期。

結構定義在本機 JSON 檔案 /tmp/myschema.json 中指定。customer_id 欄位用於叢集資料表。

bq mk \
    -t \
    --expiration 2592000 \
    --schema /tmp/myschema.json \
    --clustering_fields=customer_id \
    --description "This is my clustered table" \
    --label org:dev \
    myotherproject:mydataset.myclusteredtable

建立資料表後,您可以更新資料表的說明標籤

Terraform

使用 google_bigquery_table 資源。

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

下列範例會建立名為 mytable 的資料表,並以 IDCreated 資料欄做為叢集依據:

resource "google_bigquery_dataset" "default" {
  dataset_id                      = "mydataset"
  default_partition_expiration_ms = 2592000000  # 30 days
  default_table_expiration_ms     = 31536000000 # 365 days
  description                     = "dataset description"
  location                        = "US"
  max_time_travel_hours           = 96 # 4 days

  labels = {
    billing_group = "accounting",
    pii           = "sensitive"
  }
}

resource "google_bigquery_table" "default" {
  dataset_id          = google_bigquery_dataset.default.dataset_id
  table_id            = "mytable"
  deletion_protection = false # set to "true" in production

  clustering = ["ID", "Created"]

  schema = <<EOF
[
  {
    "name": "ID",
    "type": "INT64",
    "description": "Item ID"
  },
  {
    "name": "Item",
    "type": "STRING",
    "mode": "NULLABLE"
  },
 {
   "name": "Created",
   "type": "TIMESTAMP"
 }
]
EOF

}

如要在 Google Cloud 專案中套用 Terraform 設定,請完成下列各節的步驟。

準備 Cloud Shell

  1. 啟動 Cloud Shell
  2. 設定要套用 Terraform 設定的預設 Google Cloud 專案。

    每項專案只需要執行一次這個指令,且可以在任何目錄中執行。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    如果您在 Terraform 設定檔中設定明確值,環境變數就會遭到覆寫。

準備目錄

每個 Terraform 設定檔都必須有自己的目錄 (也稱為根模組)。

  1. Cloud Shell 中建立目錄,並在該目錄中建立新檔案。檔案名稱的副檔名必須是 .tf,例如 main.tf。在本教學課程中,這個檔案稱為 main.tf
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. 如果您正在學習教學課程,可以複製每個章節或步驟中的範例程式碼。

    將範例程式碼複製到新建立的 main.tf

    視需要從 GitHub 複製程式碼。如果 Terraform 程式碼片段是端對端解決方案的一部分,建議您使用這個方法。

  3. 查看並修改範例參數,套用至您的環境。
  4. 儲存變更。
  5. 初始化 Terraform。每個目錄只需執行一次這項操作。
    terraform init

    如要使用最新版 Google 供應商,請加入 -upgrade 選項:

    terraform init -upgrade

套用變更

  1. 檢查設定,確認 Terraform 即將建立或更新的資源符合您的預期:
    terraform plan

    視需要修正設定。

  2. 執行下列指令,並在提示中輸入 yes,即可套用 Terraform 設定:
    terraform apply

    等待 Terraform 顯示「Apply complete!」訊息。

  3. 開啟 Google Cloud 專案即可查看結果。在 Google Cloud 控制台中,前往 UI 中的資源,確認 Terraform 已建立或更新這些資源。

API

使用指定 clustering.fields 屬性和 schema 屬性的已定義資料表資源呼叫 tables.insert 方法。

Python

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

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the table to create.
# table_id = "your-project.your_dataset.your_table_name"

schema = [
    bigquery.SchemaField("full_name", "STRING"),
    bigquery.SchemaField("city", "STRING"),
    bigquery.SchemaField("zipcode", "INTEGER"),
]

table = bigquery.Table(table_id, schema=schema)
table.clustering_fields = ["city", "zipcode"]
table = client.create_table(table)  # Make an API request.
print(
    "Created clustered table {}.{}.{}".format(
        table.project, table.dataset_id, table.table_id
    )
)

Go

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

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

import (
	"context"
	"fmt"
	"time"

	"cloud.google.com/go/bigquery"
)

// createTableClustered demonstrates creating a BigQuery table with advanced properties like
// partitioning and clustering features.
func createTableClustered(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydatasetid"
	// tableID := "mytableid"
	ctx := context.Background()

	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	sampleSchema := bigquery.Schema{
		{Name: "timestamp", Type: bigquery.TimestampFieldType},
		{Name: "origin", Type: bigquery.StringFieldType},
		{Name: "destination", Type: bigquery.StringFieldType},
		{Name: "amount", Type: bigquery.NumericFieldType},
	}
	metaData := &bigquery.TableMetadata{
		Schema: sampleSchema,
		TimePartitioning: &bigquery.TimePartitioning{
			Field:      "timestamp",
			Expiration: 90 * 24 * time.Hour,
		},
		Clustering: &bigquery.Clustering{
			Fields: []string{"origin", "destination"},
		},
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, metaData); err != nil {
		return err
	}
	return nil
}

Java

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

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Clustering;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.StandardTableDefinition;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableInfo;
import com.google.cloud.bigquery.TimePartitioning;
import com.google.common.collect.ImmutableList;

public class CreateClusteredTable {
  public static void runCreateClusteredTable() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    createClusteredTable(datasetName, tableName);
  }

  public static void createClusteredTable(String datasetName, String tableName) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId tableId = TableId.of(datasetName, tableName);

      TimePartitioning partitioning = TimePartitioning.of(TimePartitioning.Type.DAY);

      Schema schema =
          Schema.of(
              Field.of("name", StandardSQLTypeName.STRING),
              Field.of("post_abbr", StandardSQLTypeName.STRING),
              Field.of("date", StandardSQLTypeName.DATE));

      Clustering clustering =
          Clustering.newBuilder().setFields(ImmutableList.of("name", "post_abbr")).build();

      StandardTableDefinition tableDefinition =
          StandardTableDefinition.newBuilder()
              .setSchema(schema)
              .setTimePartitioning(partitioning)
              .setClustering(clustering)
              .build();
      TableInfo tableInfo = TableInfo.newBuilder(tableId, tableDefinition).build();

      bigquery.create(tableInfo);
      System.out.println("Clustered table created successfully");
    } catch (BigQueryException e) {
      System.out.println("Clustered table was not created. \n" + e.toString());
    }
  }
}

從查詢結果建立叢集資料表

從查詢結果建立叢集資料表的作法有兩種:

  • 將結果寫入新的目的地資料表並指定叢集資料欄,
  • 使用 DDL CREATE TABLE AS SELECT 陳述式。如要進一步瞭解此做法,請參閱「使用資料定義語言陳述式」頁面中的從查詢結果建立叢集資料表一節。

您可以藉由查詢分區資料表或非分區資料表的方式建立叢集資料表,但不能利用查詢結果將現有的資料表變更為叢集資料表。

當您從查詢結果建立叢集資料表時,必須要使用標準 SQL。目前,系統不支援使用舊版 SQL 查詢叢集資料表或將查詢結果寫入叢集資料表。

SQL

如要從查詢結果建立叢集資料表,請使用 CREATE TABLE DDL 陳述式搭配 CLUSTER BY 選項。下列範例會查詢現有的非叢集資料表,建立依 customer_id 叢集的新資料表:

  1. 前往 Google Cloud 控制台的「BigQuery」頁面。

    前往 BigQuery

  2. 在查詢編輯器中輸入下列陳述式:

    CREATE TABLE mydataset.clustered_table
    (
      customer_id STRING,
      transaction_amount NUMERIC
    )
    CLUSTER BY
      customer_id
    AS (
      SELECT * FROM mydataset.unclustered_table
    );

  3. 按一下「執行」

如要進一步瞭解如何執行查詢,請參閱「執行互動式查詢」。

bq

輸入下列指令,從查詢結果中建立新的叢集目的地資料表:

bq --location=LOCATION query \
    --use_legacy_sql=false 'QUERY'

更改下列內容:

  • LOCATION:您位置的名稱。--location 是選用旗標。舉例來說,如果您在東京地區使用 BigQuery,就可以將旗標的值設為 asia-northeast1。您可以使用 .bigqueryrc 檔案設定位置的預設值。
  • QUERY:採用 GoogleSQL 語法的查詢。目前您無法使用舊版 SQL 查詢叢集資料表或是將查詢結果寫入叢集資料表。該查詢可包含 CREATE TABLE DDL 陳述式,以指定建立叢集資料表的選項。您可以使用 DDL 取代指定個別指令列旗標的做法。

範例:

輸入下列指令,將查詢結果寫入 mydataset 中名為 myclusteredtable 的叢集目的地資料表。mydataset 在您的預設專案中。查詢會從非分區資料表 mytable 中擷取資料,資料表的 customer_id 資料欄用於叢集資料表。資料表的 timestamp 資料欄用於建立分區資料表。

bq query --use_legacy_sql=false \
    'CREATE TABLE
       mydataset.myclusteredtable
     PARTITION BY
       DATE(timestamp)
     CLUSTER BY
       customer_id
     AS (
       SELECT
         *
       FROM
         `mydataset.mytable`
     );'

API

如要將查詢結果儲存到叢集資料表,請呼叫 jobs.insert 方法、設定 query 工作,然後加入可建立叢集資料表的 CREATE TABLE DDL 陳述式。

工作資源jobReference 區段中,利用 location 屬性指定您的位置。

在載入資料時建立叢集資料表

您載入資料到一個新的資料表時,可透過指定叢集欄的方式來建立叢集資料表。您不必在資料載入資料表之前,事先建立空白的資料表,因為您可以同時建立叢集資料表並載入資料。

有關如何載入資料的詳情,請參閱將資料載入 BigQuery 的簡介

如要在定義載入工作時定義叢集,請進行以下操作:

SQL

使用 LOAD DATA 陳述式。以下範例會載入 AVRO 資料,建立依 transaction_date 欄位分區,並依 customer_id 欄位叢集的資料表。並將分區設定為三天後失效。

  1. 前往 Google Cloud 控制台的「BigQuery」頁面。

    前往 BigQuery

  2. 在查詢編輯器中輸入下列陳述式:

    LOAD DATA INTO mydataset.mytable
    PARTITION BY transaction_date
    CLUSTER BY customer_id
      OPTIONS (
        partition_expiration_days = 3)
    FROM FILES(
      format = 'AVRO',
      uris = ['gs://bucket/path/file.avro']);

  3. 按一下「執行」

如要進一步瞭解如何執行查詢,請參閱「執行互動式查詢」。

API

如要在透過載入工作建立資料表時定義叢集設定,您可以填入資料表的 Clustering 屬性。

Go

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

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// importClusteredTable demonstrates creating a table from a load job and defining partitioning and clustering
// properties.
func importClusteredTable(projectID, destDatasetID, destTableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	gcsRef := bigquery.NewGCSReference("gs://cloud-samples-data/bigquery/sample-transactions/transactions.csv")
	gcsRef.SkipLeadingRows = 1
	gcsRef.Schema = bigquery.Schema{
		{Name: "timestamp", Type: bigquery.TimestampFieldType},
		{Name: "origin", Type: bigquery.StringFieldType},
		{Name: "destination", Type: bigquery.StringFieldType},
		{Name: "amount", Type: bigquery.NumericFieldType},
	}
	loader := client.Dataset(destDatasetID).Table(destTableID).LoaderFrom(gcsRef)
	loader.TimePartitioning = &bigquery.TimePartitioning{
		Field: "timestamp",
	}
	loader.Clustering = &bigquery.Clustering{
		Fields: []string{"origin", "destination"},
	}
	loader.WriteDisposition = bigquery.WriteEmpty

	job, err := loader.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}

	if status.Err() != nil {
		return fmt.Errorf("job completed with error: %v", status.Err())
	}
	return nil
}

Java

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

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Clustering;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.FormatOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TimePartitioning;
import com.google.common.collect.ImmutableList;

public class LoadTableClustered {

  public static void runLoadTableClustered() throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String sourceUri = "/path/to/file.csv";
    loadTableClustered(datasetName, tableName, sourceUri);
  }

  public static void loadTableClustered(String datasetName, String tableName, String sourceUri)
      throws Exception {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId tableId = TableId.of(datasetName, tableName);

      Schema schema =
          Schema.of(
              Field.of("name", StandardSQLTypeName.STRING),
              Field.of("post_abbr", StandardSQLTypeName.STRING),
              Field.of("date", StandardSQLTypeName.DATE));

      TimePartitioning partitioning = TimePartitioning.of(TimePartitioning.Type.DAY);

      Clustering clustering =
          Clustering.newBuilder().setFields(ImmutableList.of("name", "post_abbr")).build();

      LoadJobConfiguration loadJobConfig =
          LoadJobConfiguration.builder(tableId, sourceUri)
              .setFormatOptions(FormatOptions.csv())
              .setSchema(schema)
              .setTimePartitioning(partitioning)
              .setClustering(clustering)
              .build();

      Job loadJob = bigquery.create(JobInfo.newBuilder(loadJobConfig).build());

      // Load data from a GCS parquet file into the table
      // Blocks until this load table job completes its execution, either failing or succeeding.
      Job completedJob = loadJob.waitFor();

      // Check for errors
      if (completedJob == null) {
        throw new Exception("Job not executed since it no longer exists.");
      } else if (completedJob.getStatus().getError() != null) {
        // You can also look at queryJob.getStatus().getExecutionErrors() for all
        // errors, not just the latest one.
        throw new Exception(
            "BigQuery was unable to load into the table due to an error: \n"
                + loadJob.getStatus().getError());
      }
      System.out.println("Data successfully loaded into clustered table during load job");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Data not loaded into clustered table during load job \n" + e.toString());
    }
  }
}

Python

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

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the table to create.
# table_id = "your-project.your_dataset.your_table_name"

job_config = bigquery.LoadJobConfig(
    skip_leading_rows=1,
    source_format=bigquery.SourceFormat.CSV,
    schema=[
        bigquery.SchemaField("timestamp", bigquery.SqlTypeNames.TIMESTAMP),
        bigquery.SchemaField("origin", bigquery.SqlTypeNames.STRING),
        bigquery.SchemaField("destination", bigquery.SqlTypeNames.STRING),
        bigquery.SchemaField("amount", bigquery.SqlTypeNames.NUMERIC),
    ],
    time_partitioning=bigquery.TimePartitioning(field="timestamp"),
    clustering_fields=["origin", "destination"],
)

job = client.load_table_from_uri(
    ["gs://cloud-samples-data/bigquery/sample-transactions/transactions.csv"],
    table_id,
    job_config=job_config,
)

job.result()  # Waits for the job to complete.

table = client.get_table(table_id)  # Make an API request.
print(
    "Loaded {} rows and {} columns to {}".format(
        table.num_rows, len(table.schema), table_id
    )
)

控管叢集資料表的存取權

如要設定資料表和檢視表的存取權,請在下列層級為實體授予 IAM 角色 (依允許的資源範圍排序,從最大到最小):

  • Google Cloud 資源階層中的較高層級,例如專案、資料夾或機構層級
  • 資料集層級
  • 資料表或檢視表層級

您也可以使用下列方法,限制資料表中的資料存取權:

透過 IAM 保護的任何資源,存取權都是累加的。舉例來說,如果實體沒有專案等高層級的存取權,您可以授予實體資料集層級的存取權,這樣實體就能存取資料集中的資料表和檢視表。同樣地,如果實體沒有高層級或資料集層級的存取權,您可以授予實體資料表或檢視表層級的存取權。

Google Cloud資源階層中的較高層級 (例如專案、資料夾或機構層級) 授予 IAM 角色,可讓實體存取更多資源。舉例來說,在專案層級將特定角色授予實體,可讓該實體擁有適用於專案中所有資料集的權限。

在資料集層級授予角色,即可讓實體對特定資料集裡的資料表和檢視表執行指定作業,即使實體不具備更高層級的存取權也一樣。如要瞭解如何設定資料集層級的存取權控管設定,請參閱控管資料集存取權一文。

在資料表或檢視表層級授予角色,即可讓實體對特定資料表和檢視表執行指定作業,即使實體沒有較高層級的存取權也一樣。如要瞭解如何設定資料表層級的存取權控管設定,請參閱控管資料表和檢視表的存取權

您也可以建立 IAM 自訂角色。建立自訂角色之後,您就能依據要讓實體執行的特定作業授予權限。

您無法對受 IAM 保護的任何資源設定「拒絕」權限。

如要進一步瞭解角色和權限,請參閱 IAM 說明文件中的「瞭解角色」一文,以及 BigQuery 的「IAM 角色和權限」一文。

使用叢集資料表

取得叢集資料表的相關資訊

您可以透過下列方式取得資料表的相關資訊:

  • 使用 Google Cloud 控制台。
  • 使用 bq 指令列工具的 bq show 指令。
  • 呼叫 tables.get API 方法
  • 查詢 INFORMATION_SCHEMA 檢視畫面。

所需權限

您至少要具備 bigquery.tables.get 權限,才能取得資料表相關資訊。以下是具有 bigquery.tables.get 權限的預先定義 IAM 角色:

  • bigquery.metadataViewer
  • bigquery.dataViewer
  • bigquery.dataOwner
  • bigquery.dataEditor
  • bigquery.admin

此外,當具備 bigquery.datasets.create 權限的使用者建立資料集時,會獲得該資料集的 bigquery.dataOwner 存取權。bigquery.dataOwner 存取權可讓使用者取得資料集裡的資料表相關資訊。

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

取得叢集資料表資訊

如何查看叢集資料表的相關資訊:

主控台

  1. 前往 Google Cloud 控制台的「Resources」(資源) 窗格。按一下資料集名稱,即可展開該資料集,然後點選您想要查看的資料表名稱。

  2. 按一下 [Details] (詳細資料)。這個頁面會顯示包含叢集資料欄的資料表詳細資料。

    資料表詳細資料。

SQL

對於叢集資料表,您可以在 INFORMATION_SCHEMA.COLUMNS 檢視表中查詢 CLUSTERING_ORDINAL_POSITION 資料欄,找出資料表叢集資料欄中資料欄的 1 索引偏移:

  1. 前往 Google Cloud 控制台的「BigQuery」頁面。

    前往 BigQuery

  2. 在查詢編輯器中輸入下列陳述式:

    CREATE TABLE mydataset.data (column1 INT64, column2 INT64)
    CLUSTER BY column1, column2;
    SELECT
      column_name, clustering_ordinal_position
    FROM
      mydataset.INFORMATION_SCHEMA.COLUMNS;

  3. 按一下「執行」

如要進一步瞭解如何執行查詢,請參閱「執行互動式查詢」。

column1 的叢集序數位置為 1,column2 則為 2。 您可以透過 INFORMATION_SCHEMA 中的 TABLESTABLE_OPTIONSCOLUMNSCOLUMN_FIELD_PATH 檢視表,查看更多資料表中繼資料。

bq

發出 bq show 指令以顯示所有資料表資訊。使用 --schema 旗標可以只顯示資料表結構定義資訊。--format 旗標可用來控制輸出內容。

如果您要取得非預設專案中資料表的相關資訊,請使用下列格式將專案 ID 新增至資料集:project_id:dataset

bq show \
    --schema \
    --format=prettyjson \
    PROJECT_ID:DATASET.TABLE

更改下列內容:

  • PROJECT_ID:您的專案 ID
  • DATASET:資料集名稱
  • TABLE:資料表名稱

範例:

輸入下列指令,顯示 mydatasetmyclusteredtable 的所有相關資訊。mydataset 在您的預設專案中。

bq show --format=prettyjson mydataset.myclusteredtable

輸出應如下所示:

{
  "clustering": {
    "fields": [
      "customer_id"
    ]
  },
...
}

API

呼叫 bigquery.tables.get 方法,並提供所有相關參數。

列出資料集中的叢集資料表

您可以透過下列方式,列出資料集中的叢集資料表:

  • 使用 Google Cloud 控制台。
  • 使用 bq 指令列工具的 bq ls 指令。
  • 呼叫 tables.list API 方法。
  • 使用用戶端程式庫。
  • INFORMATION_SCHEMA.COLUMNS 檢視表中查詢 CLUSTERING_ORDINAL_POSITION 資料欄。

列出叢集資料表所需具備的權限及步驟,與標準資料表相同。如要進一步瞭解如何列出資料表,請參閱列出資料集中的資料表一節。

修改分群規格

您可以變更或移除資料表的叢集規格,也可以變更叢集資料表中的叢集資料欄集。如果資料表使用連續串流插入,就無法輕易透過其他方法交換,因此這種更新叢集欄集的方法非常實用。

請按照下列步驟,將新的叢集規格套用至未分區或分區資料表。

  1. 在 bq 工具中,更新資料表的叢集規格,以符合新的叢集:

     bq update --clustering_fields=CLUSTER_COLUMN DATASET.ORIGINAL_TABLE 

    更改下列內容:

    • CLUSTER_COLUMN:您要叢集化的資料欄,例如 mycolumn
    • DATASET:包含資料表的資料集名稱,例如 mydataset
    • ORIGINAL_TABLE:原始資料表的名稱,例如 mytable

    您也可以呼叫 tables.updatetables.patch API 方法來修改叢集規格

  2. 如要根據新的叢集規格將所有資料列叢集化,請執行下列 UPDATE 陳述式:

    UPDATE DATASET.ORIGINAL_TABLE SET CLUSTER_COLUMN=CLUSTER_COLUMN WHERE true

表格安全性

如要控管 BigQuery 資料表的存取權,請參閱「使用 IAM 控管資源存取權」。

後續步驟