管理分区表

本文档介绍了如何在 BigQuery 中管理分区表。提取时间分区表与分区表的管理方式相同。您可以对分区表执行以下管理任务:

  • 更新时间分区表的以下相关信息:
  • 重命名(复制)时间分区表
  • 复制时间分区表
  • 复制分区
  • 删除时间分区表
  • 删除时间分区表中的分区

如需详细了解如何创建和使用分区表(包括获取表信息、列出表以及控制表数据访问权限),请参阅创建和使用提取时间分区表创建和使用分区表

更新分区表属性

您可以更新分区表的以下相关信息:

  • 说明
  • 表过期时间
  • 分区过期时间
  • 架构定义
  • 标签

所需权限

如需更新表属性,您必须至少拥有 bigquery.tables.updatebigquery.tables.get 权限。以下预定义的 Cloud IAM 角色包含 bigquery.tables.updatebigquery.tables.get 权限:

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

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

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

更新分区表的说明

更新分区表说明的过程与更新标准表说明的过程相同。如需了解如何添加或更改表的说明,请参阅更新表的说明

目前,您不能为各个分区创建说明。

更新表过期时间

更新分区表过期时间的过程与更新标准表过期时间的过程相同。如需了解如何添加或更改表的过期时间,请参阅更新表的过期时间

更新分区过期时间

在创建分区表时,您可以通过以下方式为该表指定分区过期时间:

  • 使用 DDL ALTER TABLE 语句
  • 使用命令行工具的 bq mk 命令
  • 调用 tables.insert API 方法
  • 使用客户端库

目前,Cloud Console 或经典版 BigQuery 网页界面不支持指定分区过期时间。

如果您在创建表时指定了分区过期时间,该分区过期时间将替换数据集级层的默认分区过期时间。 设置表级层的分区过期时间后,所有分区都将遵循此过期时间。您不能对个别分区应用不同的过期时间。

表创建完毕后,您可以随时使用 CLI 的 bq update 命令或 API 的 tables.patch 方法更新表的分区过期时间。目前,Cloud Console 或经典版 BigQuery 网页界面不支持更新分区过期时间。但是,您可以使用 DDL 语句在任一界面中更新分区过期时间。

更新表的分区过期时间后,该设置将应用于所有分区,无论这些分区是何时创建的。

更新表的分区过期时间时,您必须从分区日期所对应世界协调时间 (UTC) 零点开始计算分区过期时间。

如果分区表也配置了表过期时间,则系统将依据表的过期时间设置删除相应表和其中的所有分区。表过期时间优先于分区过期时间。

例如,如果某分区表的过期时间设置为 5 天,且分区过期时间设置为 7 天,则该表及其所含的所有分区都将在 5 天后删除。

对于包含在 2016 年 12 月 13 日之前创建的分区表的项目,分区过期时间以上次修改分区的日期为准。此行为也适用于在这些项目中创建的新表。如需将项目迁移到新的行为,请使用 BigQuery 问题跟踪器递交请求。

要更新分区表的分区过期时间,请按如下所述操作:

DDL

借助数据定义语言 (DDL) 语句,您可以使用标准 SQL 查询语法创建和修改表和视图。

详细了解如何使用数据定义语言语句

如需使用 DDL 语句更新分区表的分区过期时间,请按如下所述操作:

  1. 在 Cloud Console 中打开 BigQuery 网页界面。
    转到 Cloud Console

  2. 点击编写新查询

  3. 查询编辑器文本区域中,输入您的 DDL 语句。

     ALTER TABLE mydataset.mytable
     SET OPTIONS (
       -- Sets partition expiration to 5 days
       partition_expiration_days=5
     )
     

  4. 点击运行

CLI

发出带 --time_partitioning_expiration 标志的 bq update 命令。如果您要更新非默认项目中的分区表,请按以下格式将相应项目 ID 添加到数据集名称中:project_id:dataset

bq update \
--time_partitioning_expiration integer \
project_id:dataset.table

其中:

  • integer 是表分区的默认生命周期(以秒为单位)。它没有最小值。过期时间以分区的日期加上这个整数值为准。如果您指定了 0,则分区过期时间将被移除,且分区永不过期。您必须手动删除未设定过期时间的分区。
  • project_id 是您的项目 ID。
  • dataset 是您要更新的表所属数据集的名称。
  • table 是要更新的表的名称。

示例:

输入以下命令可将 mydataset.mytable 中分区的过期时间更新为 5 天(432000 秒)。mydataset 属于默认项目。

bq update --time_partitioning_expiration 432000 mydataset.mytable

输入以下命令可将 mydataset.mytable 中分区的过期时间更新为 5 天(432000 秒)。mydataset 属于 myotherproject,而非默认项目。

bq update \
--time_partitioning_expiration 432000 \
myotherproject:mydataset.mytable

API

调用 tables.patch 方法,并使用 timePartitioning.expirationMs 属性更新分区过期时间(以毫秒为单位)。由于 tables.update 方法会替换整个表资源,因此建议使用 tables.patch 方法。

更新分区过滤条件要求

创建分区表时,您可以启用需要分区过滤条件选项来要求使用谓词过滤条件。应用此选项时,如果试图在不指定 WHERE 子句的情况下查询分区表,则会产生以下错误:Cannot query over table 'project_id.dataset.table' without a filter that can be used for partition elimination

如需详细了解如何在创建分区表时添加需要分区过滤条件选项,请参阅创建分区表

如果在创建分区表时未启用需要分区过滤条件选项,您可以更新表来添加该选项。

更新“需要分区过滤条件”选项

如需更新分区表以要求查询包含剪除分区的 WHERE 子句,请按如下所述操作:

控制台

创建分区表后,您无法使用 Cloud Console 来要求启用分区过滤条件。

经典版界面

创建分区表后,您无法使用网页界面来要求启用分区过滤条件。

CLI

要使用 CLI 更新分区表以要求启用分区过滤条件,请输入 bq update 命令并提供 --require_partition_filter 标志。

如需更新非默认项目中的分区表,请按以下格式将相应项目 ID 添加到数据集:project_id:dataset

例如:

如需更新默认项目中 mydatasetmypartitionedtable,请输入以下命令:

bq update --require_partition_filter mydataset.mytable

如需更新 myotherprojectmydatasetmypartitionedtable,请输入以下命令:

bq update --require_partition_filter myotherproject:mydataset.mytable

API

调用 tables.patch 方法,并将 requirePartitionFilter 属性设置为 true 以要求启用分区过滤条件。由于 tables.update 方法会替换整个表资源,因此建议使用 tables.patch 方法。

更新架构定义

更新分区表架构定义的过程与更新标准表架构定义的过程相同。 如需了解详情,请参阅修改表架构

重命名分区表

目前,您不能更改现有分区表的名称。如果您需要更改表名称,请按照相关步骤复制表。 在复制操作中指定目标表时,请使用新的表名称。

复制分区表

复制单个分区表

复制分区表的过程与复制标准表的过程相同。如需了解详情,请参阅复制表

复制分区表时,请注意以下事项:

  • 包含源表的数据集和包含目标表的数据集必须位于相同位置

  • 将分区表复制到新的目标分区表
    如果您将某个时间分区表复制到新表,则所有分区信息都会随该表一起复制。新表和旧表将具有相同的分区。
  • 将非分区表复制到分区表
    如果您将非分区表复制到分区表,BigQuery 会将源数据复制到表示当前日期的分区。
  • 将分区表复制到其他分区表
    要将一个分区表复制到另一个分区表,源表和目标表的分区规范必须匹配。您可以指定是将数据附加到目标表还是覆盖目标表。
  • 将分区表复制到非分区表
    如果您将分区表复制到非分区表,目标表将保持未分区状态。数据要么附加到非分区表,要么用于覆盖非分区表,具体取决于您的设置。

复制多个分区表

复制多个分区表的过程与复制多个标准表的过程相同。如需了解详情,请参阅复制多个源表

复制多个分区表时,请注意以下事项:

  • 如果将多个源表复制到同一作业中的某个分区表,则源表不能同时包含分区表和非分区表。
  • 如果所有源表都是分区表,则所有源表的分区规范必须与目标表的分区规范匹配。您的设置决定了是将数据附加到目标表还是覆盖目标表。
  • 包含源表的数据集和包含目标表的数据集必须位于相同位置

复制分区

您可以通过以下方式复制一个或多个分区:

  • 使用命令行工具的 bq cp 命令
  • 调用 jobs.insert API 方法并配置 copy 作业
  • 使用客户端库

目前,Cloud Console 或经典版 BigQuery 网页界面不支持复制分区。

所需权限

若要复制表和分区,您必须至少具有以下权限。

对于源数据集

  • bigquery.tables.get
  • bigquery.tables.getData

对于目标数据集

  • bigquery.tables.create:用于在目标数据集中创建表或分区的副本

以下预定义 Cloud IAM 角色可提供 bigquery.tables.createbigquery.tables.getbigquery.tables.getData 权限:

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

此外,若要运行复制作业,您必须具有 bigquery.jobs.create 权限。

以下预定义的 Cloud IAM 角色可提供 bigquery.jobs.create 权限:

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

此外,如果用户具有 bigquery.datasets.create 权限,则当该用户创建数据集时,系统会为其授予该数据集的 bigquery.dataOwner 访问权限。具备 bigquery.dataOwner 访问权限的用户可以复制该数据集中的表和分区,但如果目标数据集并非由该用户创建,则用户还需要具备对目标数据集的访问权限。

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

复制单个分区

控制台

Cloud Console 不支持复制分区。

经典版界面

经典版 BigQuery 网页界面不支持复制分区。

CLI

要复制分区,请使用命令行工具的 bq cp(复制)命令和分区修饰器 ($date),例如 $20160201

您可以视情况使用以下标志来控制目标分区的写入处置方式。

  • -a--append_table:用于将源分区中的数据附加到目标数据集中的现有表或分区。
  • -f--force:用于覆盖目标数据集中的现有表或分区,并且不会提示您进行确认。
  • -n--no_clobber:用于在目标数据集中已存在同名表或分区时返回以下错误消息:Table '<var>project_id:dataset.table</var> or <var>table$date</var>' already exists, skipping.。如果未指定 ,则默认行为是提示您选择是否替换目标表或分区。
  • --destination_kms_key 是客户管理的 Cloud KMS 密钥,用于加密目标表或分区。

cp 命令不支持 --time_partitioning_field--time_partitioning_type 标志。您不能使用复制作业将提取时间分区表转换为分区表。

本文未演示 --destination_kms_key。如需了解详情,请参阅使用 Cloud KMS 密钥保护数据

如果源数据集或目标数据集属于非默认项目,请按以下格式将相应项目 ID 添加到数据集名称中:project_id:dataset

(可选)添加 --location 标志并将其值设置为您的位置

bq --location=location cp \
-a -f -n \
project_id:dataset.source_table$source_partition \
project_id:dataset.destination_table$destination_partition

其中:

  • location 是您的位置的名称。--location 是可选标志。例如,如果您在东京区域使用 BigQuery,可将该标志的值设置为 asia-northeast1。您可以使用 .bigqueryrc 文件设置该位置的默认值。
  • project_id 是您的项目 ID。
  • dataset 是源数据集或目标数据集的名称。
  • source_table 是要复制的表。
  • source_partition 是源分区的分区修饰器。
  • destination_table 是目标数据集中的表名称。
  • destination_partition 是目标分区的分区修饰器。

示例:

将分区复制到新表

输入以下命令可将 mydataset.mytable 中与 2018 年 1 月 30 日对应的分区复制到新表 mydataset.mytable2mydataset 属于默认项目。

bq cp -a 'mydataset.mytable$20180130' mydataset.mytable2

将分区复制到非分区表

输入以下命令可将 mydataset.mytable 中与 2018 年 1 月 30 日对应的分区复制到非分区表 mydataset2.mytable2。使用 -a 快捷方式可将该分区的数据附加到非分区目标表。两个数据集均属于您的默认项目。

bq cp -a 'mydataset.mytable$20180130' mydataset2.mytable2

输入以下命令可将 mydataset.mytable 中与 2018 年 1 月 30 日对应的分区复制到非分区表 mydataset2.mytable2。使用 -f 快捷方式可在无提示的情况下覆盖非分区目标表。

bq --location=US cp -f 'mydataset.mytable$20180130' mydataset2.mytable2

将分区复制到其他分区表

输入以下命令可将 mydataset.mytable 中与 2018 年 1 月 30 日对应的分区复制到另一个分区表 mydataset2.mytable2。使用 -a 快捷方式可将该分区的数据附加到目标表。由于没有为目标表指定分区修饰器,因此源分区键会被保留,并且数据将被复制到目标表中与 2018 年 1 月 30 日对应的分区。您还可以为目标表指定分区修饰器,以将数据复制到特定分区。mydataset 属于默认项目。mydataset2 属于 myotherproject,而非默认项目。

bq --location=US cp \
-a \
'mydataset.mytable$20180130' \
myotherproject:mydataset2.mytable2

输入以下命令可将 mydataset.mytable 中与 2018 年 1 月 30 日对应的分区复制到另一个分区表 mydataset2.mytable2 中与 2018 年 2 月 20 日对应的分区。使用 -f 快捷方式可在无提示的情况下覆盖目标表中与 2018 年 2 月 20 日对应的分区。如果未使用分区修饰器,则目标表中的所有数据都会被覆盖。mydataset 属于默认项目。 mydataset2 属于 myotherproject,而非默认项目。

bq cp \
-f \
'mydataset.mytable$20180130' \
'myotherproject:mydataset2.mytable2$20180220'

输入以下命令可将 mydataset.mytable 中与 2018 年 1 月 30 日对应的分区复制到另一个分区表 mydataset2.mytable2mydataset 属于默认项目。mydataset2 属于 myotherproject,而非默认项目。如果目标表中存在数据,则默认情况下,系统会提示您覆盖这些数据。

bq cp \
'mydataset.mytable$20180130' \
myotherproject:mydataset2.mytable2

API

调用 jobs.insert 方法并配置 copy 作业。(可选)在作业资源 jobReference 部分的 location 属性中指定您的区域。

在作业配置中指定以下属性:

  • sourceTables 属性中输入源数据集、表和分区。
  • destinationTable 属性中输入目标数据集和表。
  • 使用 writeDisposition 属性指定是将数据附加到目标表或分区还是进行覆盖。

复制多个分区

要复制多个分区,请按如下所述操作:

控制台

目前,Cloud Console 不支持复制分区。

经典版界面

目前,经典版 BigQuery 网页界面不支持复制分区。

CLI

复制多个分区的过程与复制单个分区的过程相同,但您需要以英文逗号分隔的列表形式指定多个源分区:

bq cp \
'mydataset.mytable$20180130,mydataset.mytable$20180131' \
myotherproject:mydataset.mytable2

API

调用 jobs.insert 方法并配置 copy 作业。在作业资源 jobReference 部分的 location 属性中指定您的区域。

在作业配置中指定以下属性:

  • sourceTables 属性中输入多个源分区(包括数据集和表的名称)。
  • destinationTable 属性中输入目标数据集和表。
  • 使用 writeDisposition 属性指定是将数据附加到目标表或分区还是进行覆盖。

删除分区表

删除时间分区表及其所有分区的过程与删除标准表的过程相同。如需了解如何删除表,请参阅删除表

删除分区表中的分区

您可以使用命令行工具的 bq rm 命令或调用 tables.delete API 方法来删除分区表中的分区。目前,经典版 BigQuery 网页界面不支持删除分区。

您可以使用分区修饰器来删除特定分区。例如,可使用以下命令删除名为 mydataset.mytable 的分区表中与 2016 年 3 月 1 日对应的分区 ($20160301)。

bq rm 'mydataset.mytable$20160301'

如需检索某个分区表中的分区列表,请参阅列出提取时间分区表中的分区列出分区表中的分区

目前,您一次只能删除一个分区。

所需权限

如需删除分区,您必须至少具有 bigquery.tables.deletebigquery.tables.get 权限。以下预定义的 Cloud IAM 角色包含 bigquery.tables.deletebigquery.tables.get 权限:

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

此外,如果用户具有 bigquery.datasets.create 权限,则当该用户创建数据集时,系统会为其授予该数据集的 bigquery.dataOwner 访问权限。具备 bigquery.dataOwner 访问权限的用户可以删除该数据集中的表和分区。

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

删除分区表中的分区

您可以指定分区的修饰器来删除分区,但前提是该分区不属于特殊分区。目前,您不能删除 __NULL____UNPARTITIONED__ 分区。

要删除分区表中的某一分区,请按如下所述操作:

控制台

Cloud Console 不支持删除分区。

经典版界面

经典版 BigQuery 网页界面不支持删除分区。

CLI

使用带 --table 标志(或 -t 快捷方式)的 bq rm 命令,并引用分区修饰器 ($date) 来删除分区表中的特定分区。使用 CLI 移除分区时,您必须确认此操作。您可以使用 --force 标志(或 -f 快捷方式)跳过确认。

如果该分区表属于非默认项目中的数据集,请按以下格式将相应项目 ID 添加到数据集名称中:project_id:dataset

bq rm -f -t project_id:dataset.table$date

其中:

  • project_id 是项目 ID。
  • dataset 是该表所属数据集的名称。
  • table 是该表的名称。
  • $date 是待删除分区的修饰器。

示例:

输入以下命令可删除分区表 mydataset.mytable 中与 2016 年 3 月 1 日对应的分区 ($20160301)。mydataset 属于默认项目。

bq rm 'mydataset.mytable$20160301'

输入以下命令可删除分区表 mydataset.mytable 中与 2017 年 1 月 1 日对应的分区 ($20170101)。mydataset 属于 myotherproject,而非默认项目。

bq rm 'myotherproject:mydataset.mytable$20170101'

输入以下命令可删除分区表 mydataset.mytable 中与 2018 年 1 月 18 日对应的分区 ($20180118)。mydataset 属于 myotherproject,而非默认项目。可使用 -f 快捷方式跳过确认。

bq rm -f 'myotherproject:mydataset.mytable$20180118'

API

调用 tables.delete 方法,并使用 tableId 参数指定表和分区的修饰器。