管理分区表
本文档介绍了如何在 BigQuery 中管理分区表。
获取分区元数据
您可以通过以下方式来获取有关分区表的信息:
- 使用
INFORMATION_SCHEMA.PARTITIONS
视图(预览版)。 - 使用
__PARTITIONS_SUMMARY__
元表(仅限旧版 SQL)。
使用 INFORMATION_SCHEMA
视图获取分区元数据
当您查询 INFORMATION_SCHEMA.PARTITIONS
视图时,每个分区都会有一行对应的查询结果。例如,以下查询列出了名为 mydataset
的数据集中的所有表分区:
SELECT table_name, partition_id, total_rows
FROM `mydataset.INFORMATION_SCHEMA.PARTITIONS`
WHERE partition_id IS NOT NULL
如需了解详情,请参阅 INFORMATION_SCHEMA.PARTITIONS
。
使用元表获取分区元数据
在旧版 SQL 中,您可以通过查询 __PARTITIONS_SUMMARY__
元表来获取表分区的元数据。元表是包含元数据的只读表。
按如下方式查询 __PARTITIONS_SUMMARY__
元表:
#legacySQL SELECT column FROM [dataset.table$__PARTITIONS_SUMMARY__]
__PARTITIONS_SUMMARY__
元表具有以下列:
值 | 说明 |
---|---|
project_id |
项目名称。 |
dataset_id |
数据集名称。 |
table_id |
时间分区表的名称。 |
partition_id |
分区的名称(日期)。 |
creation_time |
创建分区的时间,以从 UTC 1970 年 1 月 1 日起计算的毫秒数表示。 |
last_modified_time |
上次修改分区的时间,以从 UTC 1970 年 1 月 1 日起计算的毫秒数表示。 |
如需运行使用 __PARTITIONS_SUMMARY__
元表的查询作业,您至少必须具有 bigquery.jobs.create
权限和 bigquery.tables.getData
权限。
要详细了解 BigQuery 中的 IAM 角色,请参阅访问权限控制。
设置分区过失效时间
当您创建按注入时间或时间单位列分区的表时,可以指定分区过期时间。此设置指定 BigQuery 在每个分区中保留数据的时长。该设置适用于表中的所有分区,但系统会根据分区时间独立计算每个分区的设置。
分区的到期时间根据分区边界(采用世界协调时间 (UTC))计算。例如,对于每日分区,分区边界在午夜零点(00:00:00 UTC)开始。如果表的分区到期时间为 6 小时,则每个分区将在次日 06:00:00 UTC 到期。 分区过期后,BigQuery 将删除该分区中的数据。
您还可以在数据集级层指定默认分区到期时间。如果您为表设置了分区到期时间,则该值会替换默认分区到期时间。如果未指定任何分区到期时间(表或数据集),则分区将永不过期。
如果您设置了表到期时间,则该值优先于分区到期时间。例如,如果表到时间设置为 5 天,分区到期时间设置为 7 天,则该表及其所含的所有分区都将在 5 天后删除。
表创建完毕后,您可以随时更新表的分区到期时间。新设置将应用于该表中的所有分区,无论这些分区是何时创建的。如果现有分区早于新的到期时间,则会立即过期。
如果某个分区过期,该分区中的数据将无法再用于查询,而您不需要为该分区的存储空间付费。BigQuery 最终会删除已过期的分区。在此之前,分区将计入表配额。如需立即删除分区,您可以手动删除分区。
对于在 2016 年 12 月 13 日之前创建的项目,分区到期时间基于分区的上次修改日期。此行为适用于项目中创建的现有表和新表。如需将项目迁移到新的行为,请使用 BigQuery 问题跟踪器创建请求。
更新分区过失效时间
要更新分区表的分区过期时间,请按如下所述操作:
控制台
您无法在控制台中更新分区到期时间。
SQL
使用 ALTER TABLE SET OPTIONS
语句。以下示例会将到期时间更新为 5 天。要移除表的分区到期时间,请将 partition_expiration_days
设置为 NULL
。
在控制台中,转到 BigQuery 页面。
在查询编辑器中,输入以下语句:
ALTER TABLE mydataset.mytable SET OPTIONS ( -- Sets partition expiration to 5 days partition_expiration_days = 5);
点击
运行。
如需详细了解如何运行查询,请参阅运行交互式查询。
bq
发出带 --time_partitioning_expiration
标志的 bq update
命令。如果您要更新非默认项目中的分区表,请按以下格式将相应项目 ID 添加到数据集名称中:project_id:dataset
。
bq update \ --time_partitioning_expiration integer_in_seconds \ --time_partitioning_type unit_time \ project_id:dataset.table
其中:
- integer 是表分区的默认生命周期(以秒为单位)。它没有最小值。过期时间以分区的日期加上这个整数值为准。如果您指定了
0
,则分区过期时间将被移除,且分区永不过期。您必须手动删除没有过期时间的分区。 - unit_time 是
DAY
、HOUR
、MONTH
或YEAR
,具体取决于表的分区粒度。此值必须与您在创建表时设置的粒度一致。 - 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
子句)。此设置可以提高性能并降低费用,因为 BigQuery 可以使用过滤条件来删减与谓词不匹配的分区。
如需了解如何在创建分区表时添加需要分区过滤条件选项,请参阅创建分区表。
如果分区表具有需要分区过滤条件设置,则该表上的每个查询都必须包含至少一个仅引用分区列的谓词。不含此类谓词的查询会返回以下错误:
Cannot query over table 'project_id.dataset.table' without a
filter that can be used for partition elimination
。
如需了解详情,请参阅查询分区表。
更新分区过滤条件要求
如果在创建分区表时未启用需要分区过滤条件选项,您可以更新表来添加该选项。
控制台
创建分区表后,您无法使用控制台来要求启用分区过滤条件。
SQL
使用 ALTER TABLE SET OPTIONS
语句更新分区过滤条件要求。以下示例将要求更新为 true
:
在控制台中,转到 BigQuery 页面。
在查询编辑器中,输入以下语句:
ALTER TABLE mydataset.mypartitionedtable SET OPTIONS ( require_partition_filter = true);
点击
运行。
如需详细了解如何运行查询,请参阅运行交互式查询。
bq
如需使用 bq
命令行工具更新分区表以要求启用分区过滤条件,请输入 bq update
命令并提供 --require_partition_filter
标志。
如需在非默认项目中更新分区表,请按以下格式将相应项目 ID 添加到数据集内:project_id:dataset。
例如:
如需更新默认项目中 mydataset
的 mypartitionedtable
,请输入以下命令:
bq update --require_partition_filter mydataset.mytable
如需更新 myotherproject
中 mydataset
的 mypartitionedtable
,请输入以下命令:
bq update --require_partition_filter myotherproject:mydataset.mytable
API
调用 tables.patch
方法,并将 requirePartitionFilter
属性设置为 true
以要求启用分区过滤条件。由于 tables.update
方法会替换整个表资源,因此建议使用 tables.patch
方法。
Java
试用此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Java 设置说明进行操作。如需了解详情,请参阅 BigQuery Java API 参考文档。
复制分区表
复制分区表的过程与复制标准表的过程相同。如需了解详情,请参阅复制表。
复制分区表时,请注意以下事项:
- 将分区表复制到新的目标表
- 所有分区信息都会随该表一起复制。新表和旧表将具有相同的分区。
- 将非分区表复制到现有分区表
- 此操作仅支持提取时间分区。BigQuery 会将源数据复制到表示当前日期的分区。时间单位列分区表或整数范围分区表不支持此操作。
- 将一个分区表复制到另一个分区表
- 源表和目标表的分区规范必须匹配。
- 将分区表复制到非分区表
- 目标表保持未分区状态。
- 复制多个分区表
如果将多个源表复制到同一作业中的某个分区表,则源表不能同时包含分区表和非分区表。
如果所有源表都是分区表,则所有源表的分区规范必须与目标表的分区规范匹配。
复制到现有表时,您可以指定是附加到目标表还是覆盖目标表。
复制各个分区
您可以将一个或多个分区中的数据复制到另一个表。
控制台
控制台不支持复制分区。
bq
如需复制分区,请使用 bq
命令行工具的 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.
。如果未指定-n
,则默认行为是提示您选择是否替换目标表或分区。--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.mytable2
。mydataset
属于默认项目。
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.mytable2
。mydataset
属于默认项目。mydataset2
属于 myotherproject
,而非默认项目。如果目标表中存在数据,则默认情况下,系统会提示您覆盖这些数据。
bq cp \
'mydataset.mytable$20180130' \
myotherproject:mydataset2.mytable2
如需复制多个分区,请以英文逗号分隔列表的形式指定这些分区:
bq cp \ 'mydataset.mytable$20180130,mydataset.mytable$20180131' \ myotherproject:mydataset.mytable2
API
调用 jobs.insert
方法并配置 copy
作业。(可选)在作业资源 jobReference
部分的 location
属性中指定您的区域。
在作业配置中指定以下属性:
- 在
sourceTables
属性中输入源数据集、表和分区。 - 在
destinationTable
属性中输入目标数据集和表。 - 使用
writeDisposition
属性指定是将数据附加到目标表或分区还是进行覆盖。
如需复制多个分区,请在 sourceTables
属性中输入源分区(包括数据集和表名称)。
删除分区
您可以从分区表中删除个别分区。但是,您无法删除特殊的 __NULL__
或 __UNPARTITIONED__
分区。
您一次只能删除一个分区。
如需删除某一分区,您可以指定分区的修饰器,除非该分区是两种特殊分区之一。
如需删除分区表中的某一分区,请按如下所述操作:
控制台
控制台不支持删除分区。
bq
使用带有 --table
标志(或 -t
快捷方式)的 bq rm
命令,并指定分区修饰器以删除特定分区。
bq rm --table project_id:dataset.table$partition
其中:
- project_id 是项目 ID。如果省略,则系统会使用默认项目。
- dataset 是包含表的数据集的名称。
- table 是表的名称。
- partition 是您要删除的分区的分区修饰器。
分区修饰器具有以下格式(具体取决于分区类型):
- 每小时分区:
yyyymmddhh
。示例:$2016030100
。 - 每日分区:
yyyymmdd
。示例:$20160301
。 - 每月分区:
yyyymm
。示例:$201603
。 - 每年分区:
yyyy
。示例:$2016
。 - 整数范围分区:分区范围的开始。示例:
$20
。
bq
命令行工具会提示您确认操作。如需跳过确认,请使用 --force
标志(或 -f
快捷方式)。
示例:
删除默认项目中名为 mydataset.mytable
的每日分区表中 2016 年 3 月 1 日的分区:
bq rm --table 'mydataset.mytable$20160301'
在每月分区表中删除 2016 年 3 月的分区:
bq rm --table 'mydataset.mytable$201603'
从名为 mydataset.mytable
的整数范围分区表中删除从 20 开始的整数范围:
bq rm --table 'mydataset.mytable$20'
API
调用 tables.delete
方法,并使用 tableId
参数指定表和分区的修饰器。
分区表安全性
分区表的访问权限控制与标准表的访问权限控制相同。如需了解详情,请参阅表访问权限控制简介。