创建和使用聚簇表

本文档介绍如何在 BigQuery 中创建和使用聚簇表。如需大致了解 BigQuery 中的聚簇表支持,请参阅聚簇表简介

限制

BigQuery 中的聚簇表存在以下限制:

  • 仅支持使用标准 SQL 查询聚簇表以及将查询结果写入聚簇表。
  • 聚簇列必须是以下任一类型的顶级非重复列:

    • DATE
    • BOOL
    • GEOGRAPHY
    • INT64
    • NUMERIC
    • STRING
    • TIMESTAMP

    如需详细了解数据类型,请参阅标准 SQL 数据类型

  • 您最多可以指定四个聚簇列。

  • 使用 STRING 类型的列进行聚簇时,BigQuery 仅使用前 1024 个字符为数据划分聚簇。列中的值本身可以超过 1024 个字符。

创建聚簇表

您可以通过以下方式创建聚簇表:

表命名

在 BigQuery 中创建表时,数据集中每个表的名称都必须具有唯一性。表名称可:

  • 包含最多 1024 个字符。
  • 包含类别 L(字母)、M(符号)、N(数字)、Pc(连接符,包括下划线)、Pd(短划线)、Zs(空格)中的 Unicode 字符。如需了解详情,请参阅常规类别

例如,以下都是有效的表名称:table-01ग्राहक00_お客様étudiant

所需权限

如需创建表,您至少必须具有以下权限:

  • bigquery.tables.create:创建表的权限
  • bigquery.tables.updateData:使用加载作业、查询作业或复制作业向表中写入数据
  • bigquery.jobs.create:用于运行向表中写入数据的查询作业、加载作业或复制作业

如需访问向表中写入的数据,可能还需要其他权限,例如 bigquery.tables.getData

以下预定义的 IAM 角色同时包含 bigquery.tables.createbigquery.tables.updateData 权限:

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

以下预定义的 IAM 角色包含 bigquery.jobs.create 权限:

  • bigquery.user
  • bigquery.jobUser
  • bigquery.admin

此外,如果用户具有 bigquery.datasets.create 权限,则当该用户创建数据集时,系统会为其授予该数据集的 bigquery.dataOwner 访问权限。借助 bigquery.dataOwner 访问权限,用户可以在数据集内创建和更新表。

如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅预定义的角色和权限

遵循架构定义创建空聚簇表

在 BigQuery 中创建表时,您可以指定聚簇列。创建表后,您可以修改聚簇列;如需了解详情,请参阅修改聚簇规范

聚簇列必须是以下任一简单数据类型的顶级非重复列:

  • DATE
  • BOOLEAN
  • GEOGRAPHY
  • INTEGER
  • NUMERIC
  • STRING
  • TIMESTAMP

您最多可以指定四个聚簇列。指定多个列时,对列进行指定的顺序决定了数据的排序方式。例如,如果表按 a、b 和 c 列进行聚簇,则数据按相同顺序排序:首先按 a 列排序,然后按 b 列排序,最后按 c 列排序。最佳做法是将最常过滤或聚合的列放在首位。

聚簇列的顺序也会影响查询性能和价格。如需详细了解查询聚簇表的最佳做法,请参阅查询聚簇表

要创建遵循某个架构定义的空聚簇表,请执行以下操作:

控制台

  1. 在 Google Cloud Console 中,转到 BigQuery 页面。

    转到 BigQuery 页面

  2. 在导航面板的资源部分中,展开您的项目并选择数据集。

  3. 在窗口右侧的详细信息面板中,点击创建表

    “创建表”按钮。

  4. 创建表页面的来源部分,为基于以下数据创建表选择空表

    “基于以下数据创建表”选项。

  5. 目标位置下:

    • 对于数据集名称,选择相应的数据集,然后在表名称字段中输入要创建的表的名称。
    • 确认表类型设置为原生表
  6. 架构下,输入架构定义。

    • 通过以下方式,手动输入架构信息:

      • 启用以文本形式修改,并以 JSON 数组格式输入表架构。

      • 使用添加字段手动输入架构。

  7. (可选)在分区和聚簇设置下,选择按字段分区 (Partition by field),然后选择 DATETIMESTAMP 列。如果架构不包含 DATETIMESTAMP 列,则此选项不可用。

    要创建提取时间分区表,请选择按提取时间分区

  8. (可选)在分区过滤条件中,点击需要分区过滤条件复选框,以要求用户添加 WHERE 子句来指定要查询的分区。要求分区过滤条件可以减少费用并提高性能。如需了解详情,请参阅查询分区表

  9. 对于聚簇顺序,请输入一至四个以英文逗号分隔的列名称。

  10. (可选)点击高级选项,然后在加密部分点击客户管理的密钥以使用 Cloud Key Management Service 密钥。如果保留 Google 管理的密钥设置,BigQuery 将对静态数据进行加密

  11. 点击创建表

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 \
--time_partitioning_type=DAY \
--time_partitioning_field PARTITION_COLUMN \
--clustering_fields CLUSTER_COLUMNS \
--time_partitioning_expiration INTEGER2 \
--description "DESCRIPTION" \
--label KEY:VALUE,KEY:VALUE \
PROJECT_ID:DATASET.TABLE

替换以下内容:

  • INTEGER1:表的默认生命周期(以秒为单位)。最小值为 3600 秒(一小时)。到期时间以当前世界协调时间 (UTC) 加上这个整数值为准。如果您在创建时间分区表时设置了该表的到期时间,则系统会忽略数据集的默认表到期时间设置。如果设置了此值,系统将在指定的时间后删除表和所有分区。
  • SCHEMA:采用 COLUMN:DATA_TYPE,COLUMN:DATA_TYPE 格式的内嵌架构定义,或者是本地机器上 JSON 架构文件的路径。
  • PARTITION_COLUMN:用于创建分区表的 TIMESTAMPDATE 列的名称。如果您创建分区表,则无需指定 --time_partitioning_type=DAY 标志。
  • CLUSTER_COLUMNS:英文逗号分隔的聚簇列(最多 4 个)列表。该列表不能包含任何空格。
  • INTEGER2:表分区的默认生命周期(以秒为单位)。它没有最小值。过期时间以分区的日期加上这个整数值为准。分区过期时间虽然与表的过期时间无关,但它不会替换表的过期时间。如果设置的分区过期时间超过了表的过期时间,则以表过期时间为准。
  • DESCRIPTION:加英文引号的表说明。
  • KEY:VALUE:代表标签的键值对。您可以使用英文逗号分隔列表输入多个标签。
  • PROJECT_ID:您的项目 ID。
  • DATASET:项目中的数据集。
  • TABLE:您要创建的分区表的名称。

在命令行中指定架构时,您不能添加 RECORD (STRUCT) 类型和列说明,也不能指定列的模式。所有模式均默认为 NULLABLE。如需添加说明、模式和 RECORD 类型,请改为提供 JSON 架构文件

示例:

输入以下命令,在默认项目的 mydataset 中创建一个名为 myclusteredtable 的聚簇表。该表是一个分区表(按 TIMESTAMP 列分区)。分区的过期时间设置为 86400 秒(1 天),表的过期时间设置为 2592000(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' \
--time_partitioning_field timestamp \
--clustering_fields customer_id \
--time_partitioning_expiration 86400  \
--description "This is my clustered table" \
--label org:dev \
mydataset.myclusteredtable

输入以下命令,在 myotherproject(非默认项目)中创建一个名为 myclusteredtable 的聚簇表。该表是一个提取时间分区表。分区过期时间设为 259200 秒(3天),说明设为 This is my partitioned table,标签设为 organization:development。该命令使用 -t 快捷方式代替 --table。此命令没有指定表过期时间。如果相关数据集有默认的表过期时间,则系统会应用该过期时间。如果数据集没有默认的表到期时间,则该表将永不过期,但该分区会在 3 天后过期。

相应架构在如下本地 JSON 文件中指定:/tmp/myschema.jsoncustomer_id 字段用于聚簇分区。

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

创建分区表后,您可以更新该表的表过期时间分区过期时间说明标签

API

使用指定了 timePartitioning 属性、clustering.fields 属性和 schema 属性的已定义表资源调用 tables.insert 方法。

Python

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

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 参考文档

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 参考文档

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());
    }
  }
}

基于查询结果创建聚簇表

您可以通过以下两种方法,基于查询结果创建聚簇表:

您可以通过查询分区表或非分区表来创建聚簇表。但不能使用查询结果将现有表更改为聚簇表。

基于查询结果创建聚簇表时,您必须使用标准 SQL。目前,无法使用旧版 SQL 查询聚簇表或将查询结果写入聚簇表。

控制台

使用 Cloud Console 查询数据时,除非使用 DDL 语句,否则无法为目标表指定聚簇选项。如需了解详情,请参阅使用数据定义语言语句

bq

输入以下命令,基于查询结果创建一个新的聚簇目标表:

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

请替换以下内容:

  • LOCATION:您的位置名称。--location 是可选标志。例如,如果您在东京地区使用 BigQuery,可将该标志的值设置为 asia-northeast1。您可以使用 .bigqueryrc 文件设置位置的默认值。
  • QUERY:使用标准 SQL 语法的查询。目前,无法使用旧版 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 简介

要在定义加载作业时定义聚簇,请执行以下操作:

API

要在通过加载作业创建表时定义聚簇配置,您可以为该表填充 Clustering 属性。

Go

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

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 参考文档

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 参考文档

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 角色,这些级层按照允许的资源范围从大到小依次排列:

对受 IAM 保护的任何资源的访问权限具有附加性。例如,如果某个实体没有项目等较高级层的访问权限,您可以在数据集级层向该实体授予访问权限,然后该实体便将有权访问该数据集中的表和视图。同样,如果实体没有较高级层或数据集级层的访问权限,您可以在表或视图级层向该实体授予访问权限。

Google Cloud 资源层次结构中授予更高级层(例如项目、文件夹或组织级层)的 IAM 角色,使实体可访问一组广泛的资源。例如,在项目级为实体授予角色会为该实体提供整个项目中所有数据集的访问权限。

在数据集级层授予角色可指定允许实体对该特定数据集中的表和视图执行的操作,即使实体没有更高级层的访问权限也可执行这些操作。如需详细了解如何配置数据集级层的访问权限控制,请参阅控制对数据集的访问权限

在表或视图级层授予角色可指定允许实体对特定表和视图执行的操作,即使实体没有更高级层的访问权限也可执行这些操作。如需了解如何配置表级层的访问权限控制,请参阅控制对表和视图的访问权限

您还可以创建 IAM 自定义角色。如果创建自定义角色,则您授予的权限取决于您希望实体能够执行的具体操作。

您无法对受 IAM 保护的任何资源设置“拒绝”权限。

如需详细了解角色和权限,请参阅:

使用聚簇表

获取有关聚簇表的信息

您可以通过以下方式来获取有关表的信息:

  • 使用 Cloud Console。
  • 使用 bq 命令行工具的 bq show 命令。
  • 调用 tables.get API 方法。
  • 查询 INFORMATION_SCHEMA 视图。

所需权限

如需获取有关表的信息,您至少必须获得 bigquery.tables.get 权限。以下预定义的 IAM 角色包含 bigquery.tables.get 权限:

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

此外,如果用户具有 bigquery.datasets.create 权限,则当该用户创建数据集时,系统会为其授予该数据集的 bigquery.dataOwner 访问权限。借助 bigquery.dataOwner 访问权限,用户可以获取数据集内表的信息。

如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅预定义的角色和权限

获取聚簇表信息

要查看聚簇表的相关信息,请执行以下操作:

控制台

  1. 在 Google Cloud Console 中,转到 资源窗格。点击数据集名称将其展开,然后点击要查看的表名称。

  2. 点击详细信息。此页面会显示表的详细信息,包括聚簇列。

    表详细信息。

bq

发出 bq show 命令可显示所有表信息。使用 --schema 标志可仅显示表的架构信息。--format 标志可用于控制输出。

如果您要获取非默认项目中的表信息,请按以下格式将相应项目 ID 添加到数据集:project_id:dataset

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

替换以下内容:

  • PROJECT_ID:您的项目 ID
  • DATASET:数据集的名称
  • TABLE:表格的名称

示例:

输入以下命令可显示 mydataset 中有关 myclusteredtable 的所有信息。mydataset 属于默认项目。

bq show --format=prettyjson mydataset.myclusteredtable

输出应如下所示:

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

API

调用 bigquery.tables.get 方法并提供所有相关参数。

SQL

对于聚簇表,您可以查询 INFORMATION_SCHEMA.COLUMNS 视图中的 CLUSTERING_ORDINAL_POSITION 列,检索表的聚簇列的相关信息。

-- Set up a table with clustering.
CREATE TABLE myDataset.data (column1 INT64, column2 INT64)
PARTITION BY _PARTITIONDATE
CLUSTER BY column1, column2;

-- This query returns 1 for column1 and 2 for column2.
SELECT column_name, clustering_ordinal_position
FROM myDataset.INFORMATION_SCHEMA.COLUMNS;

通过 INFORMATION_SCHEMA 中的 TABLESTABLE_OPTIONSCOLUMNSCOLUMN_FIELD_PATH 视图,可查看更多表元数据。

列出数据集中的聚簇表

您可以通过以下方式列出数据集中的聚簇表:

  • 使用 Cloud Console。
  • 使用 bq 命令行工具的 bq ls 命令。
  • 调用 tables.list API 方法。
  • 使用客户端库。
  • INFORMATION_SCHEMA.COLUMNS 视图中查询 CLUSTERING_ORDINAL_POSITION 列。

列出聚簇表所需的权限以及步骤与列出分区表相同。如需详细了解如何列出表,请参阅列出数据集中的分区表

修改聚簇规范

通过调用 tables.updatetables.patch 方法,可以更改或移除表聚簇规范。还可以将聚簇表中的聚簇列集更改为其他列集。这种聚簇列集更新方法对支持连续流式插入的表最有用,因为使用其他方法无法轻松交换这些表。

如果将表从非聚簇转换为聚簇,或者聚簇列集发生更改,则自动重新聚簇仅从那时起才起作用。例如,如果使用 tables.update 将大小为 1 PB 的非聚簇表转换为聚簇表,转换后的表仍会包含 1 PB 的非聚簇数据。自动重新聚簇仅适用于更新后提交到表的所有新数据。

后续步骤