管理分區資料表

本文說明如何在 BigQuery 中管理分區資料表。

取得分區中繼資料

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

使用 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 分區的建立時間,從世界標準時間 1970 年 1 月 1 日開始計算,並以毫秒為單位。
last_modified_time 分區的前次修改時間,從世界標準時間 1970 年 1 月 1 日開始計算,並以毫秒為單位。

如要執行使用 __PARTITIONS_SUMMARY__ 中繼資料表的查詢工作,您至少必須具備 bigquery.jobs.create 權限和 bigquery.tables.getData 權限。

如要深入瞭解 BigQuery 中的 IAM 角色,請參閱存取權控管

設定分區到期時間

建立以擷取時間或時間單位資料欄分區的資料表時,您可以指定分區到期時間。這項設定會指定 BigQuery 保留各個分區資料的時間長度。這項設定會套用至資料表中的所有分區,但會根據分區時間為每個分區單獨計算。

分區的到期時間會以世界標準時間計算,並以分區邊界為準。舉例來說,如果使用每日分區,分區邊界會設在午夜 (世界標準時間 00:00:00)。如果資料表的分區到期時間為 6 小時,則每個分區的到期時間為隔天 06:00:00 (世界標準時間)。分區到期後,BigQuery 會刪除該分區中的資料。

您也可以在資料集層級指定預設分區到期時間。如果您在資料表上設定分區到期時間,該值會覆寫預設分區到期時間。如果您未指定任何分區到期時間 (在資料表或資料集中),則分區永遠不會到期。

如果您設定了資料表到期時間,該值會優先於分區到期時間。例如,如果資料表到期時間設定為 5 天,而分區的到期時間設定為 7 天,則資料表與其中的所有分區會在 5 天之後刪除。

建立資料表後,您隨時可以更新資料表的分區到期時間。無論分區何時建立,新設定都會套用到該資料表的所有分區。如果現有分區的建立時間早於新設定的到期時間,則會立即到期。同樣地,如果資料複製或插入至以時間單位欄分區的資料表,則任何比資料表設定的分區到期時間更久的分區都會立即到期。

分區到期後,BigQuery 會刪除該分區。系統會根據時間回溯安全防護政策保留分割區資料,並視您的帳單模式收取費用。在此之前,分區數量會用於計算資料表配額。如要立即刪除分區,您可以手動刪除分區

更新分區到期時間

更新分區資料表的分區到期時間:

主控台

您無法在 Google Cloud 控制台中更新分區到期時間。

SQL

使用 ALTER TABLE SET OPTIONS 陳述式。以下範例會將到期日更新為 5 天。如要移除資料表的分區到期日,請將 partition_expiration_days 設為 NULL

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

    前往 BigQuery

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

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

  3. 按一下 「Run」

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

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 會根據資料表的分區精細程度,採用 DAYHOURMONTHYEAR。這個值必須與您在建立資料表時設定的精細程度相符。
  • project_id 是您的專案 ID。
  • dataset 是含有您要更新資料表的資料集名稱。
  • table 是您要更新之資料表的名稱。

範例:

輸入下列指令,將 mydataset.mytable 中的分區到期時間更新為 5 天 (432000 秒)。mydataset 在您的預設專案中。

bq update --time_partitioning_expiration 432000 mydataset.mytable

輸入下列指令,將 mydataset.mytable 中的分區到期時間更新為 5 天 (432000 秒)。mydatasetmyotherproject 中,而不是您的預設專案中。

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

API

呼叫 tables.patch 方法,並使用 timePartitioning.expirationMs 屬性來更新分區到期時間 (以毫秒為單位)。由於 tables.update 方法會取代整個資料表資源,因此建議使用 tables.patch 方法。

設定分區篩選器必要條件

建立分區資料表時,您可以要求資料表上的所有查詢都必須包含述詞篩選器 (WHERE 子句),以便篩選分區欄。這項設定可提升效能並降低成本,因為 BigQuery 可以使用篩選器來裁減不符合述詞的分區。這項規定也適用於檢視表和具體化檢視表的查詢,前提是這些查詢會參照分區資料表。

如要瞭解如何在建立分區資料表時新增「Require partition filter」選項,請參閱「建立分區資料表」一節。

如果分區資料表設有「Require partition filter」設定,則該資料表的每個查詢都必須至少包含一個只參照分區欄的述詞。不含這類述詞的查詢會傳回以下錯誤:

Cannot query over table 'project_id.dataset.table' without a filter that can be used for partition elimination

詳情請參閱查詢分區資料表一文。

更新分區篩選器必要條件

如果您在建立分區資料表時未啟用「Require partition filter」(需要分區篩選器) 選項,可以更新資料表以新增該選項。

主控台

建立分區資料表後,您就無法使用 Google Cloud 主控台來要求使用分區篩選器。

SQL

使用 ALTER TABLE SET OPTIONS 陳述式更新分區篩選器必要條件。以下範例會將要求更新為 true

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

    前往 BigQuery

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

    ALTER TABLE mydataset.mypartitionedtable
      SET OPTIONS (
        require_partition_filter = true);

  3. 按一下 「Run」

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

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 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Table;

// Sample to update require partition filter on a table.
public class UpdateTableRequirePartitionFilter {

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

  public static void updateTableRequirePartitionFilter(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();

      Table table = bigquery.getTable(datasetName, tableName);
      table.toBuilder().setRequirePartitionFilter(true).build().update();

      System.out.println("Table require partition filter updated successfully");
    } catch (BigQueryException e) {
      System.out.println("Table require partition filter was not updated \n" + e.toString());
    }
  }
}

複製分區資料表

複製分區資料表的程序,與複製標準資料表的程序相同。詳情請參閱複製資料表一節。

複製分區資料表時,請注意以下幾點:

  • 將分區資料表複製到新的目的地資料表
    所有分區資訊都會隨資料表一起複製。新資料表與舊資料表的分區相同。
  • 將非分區資料表複製到現有分區資料表
    這項操作僅支援擷取時間分割作業。BigQuery 會將來源資料複製到代表目前日期的分區。這項作業不支援時間單位欄分區或整數範圍分區的資料表。
  • 將分區資料表複製到其他分區資料表
    來源和目的地資料表的分區指定必須相符。
  • 將分區資料表複製到非分區資料表
    目的地資料表仍為非分區。
  • 複製多個分區資料表

    如果您將多個來源資料表複製到相同工作中的分區資料表,來源資料表不能同時包含分區與非分區資料表。

    如果所有來源資料表都是分區資料表,則所有來源資料表的分區設定都必須符合目的地資料表的分區設定。

  • 複製含有叢集規格的分區資料表

    如果您複製到新資料表,所有叢集資訊都會隨資料表一起複製。新資料表與舊資料表的叢集相同。

    如果您複製至現有資料表,來源和目的地資料表的叢集規格必須相符。

複製至現有資料表時,您可以指定要附加還是覆寫目的地資料表。

複製個別分區

您可以將一或多個分區的資料複製到其他資料表。

主控台

Google Cloud 主控台不支援複製分區。

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 是目的地分區的分區裝飾符。

範例:

將分區複製到新資料表

輸入下列指令,將 2018 年 1 月 30 日的分區從 mydataset.mytable 複製到新資料表:mydataset.mytable2mydataset 在您的預設專案中。

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

將分區複製到非分區資料表

輸入下列指令,將 2018 年 1 月 30 日的分區從 mydataset.mytable 複製到非分區資料表:mydataset2.mytable2-a 捷徑可用來將分區的資料附加至非分區目的地資料表。兩個資料集都在您的預設專案中。

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

輸入下列指令,將 2018 年 1 月 30 日的分區從 mydataset.mytable 複製到非分區資料表:mydataset2.mytable2-f 捷徑可用來在無提示的情況下覆寫非分區目的地資料表。

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

將分區複製到其他分區資料表

輸入下列指令,將 2018 年 1 月 30 日的分區從 mydataset.mytable 複製到其他分區資料表:mydataset2.mytable2-a 捷徑可用來將分區的資料附加至目的地資料表。由於目的地資料表上未指定分區修飾符,因此會保留來源分區索引鍵,並將資料複製到目的地資料表中 2018 年 1 月 30 日的分區。您也可以在目的地資料表上指定分區修飾符,將資料複製到指定的分區。mydataset 在您的預設專案中。mydataset2myotherproject 中,而不是您的預設專案中。

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

輸入下列指令,將 2018 年 1 月 30 日的分區從 mydataset.mytable 複製到另一個分區資料表 mydataset2.mytable2 的 2018 年 1 月 30 日分區。-f 捷徑可用來在無提示的情況下覆寫目的地資料表中 2018 年 1 月 30 日的分區。如未使用分區修飾符,則會覆寫目的地資料表中的所有資料。mydataset 在您的預設專案中。mydataset2myotherproject 中,而不是您的預設專案中。

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

輸入下列指令,將 2018 年 1 月 30 日的分區從 mydataset.mytable 複製到其他分區資料表:mydataset2.mytable2mydataset 在您的預設專案中。mydataset2myotherproject 中,而不是您的預設專案中。如果目的地資料表中有資料,則預設行為是提示您進行覆寫。

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__ 分區。

您一次只能刪除一個分區。

您可以指定分區的修飾符來刪除分區,但有兩個特殊分區是例外。

刪除分區資料表中的分區:

主控台

Google Cloud 主控台不支援刪除分區。

SQL

如果符合條件的 DELETE 陳述式涵蓋分區中的所有資料列,BigQuery 就會移除整個分區。這項移除作業不會掃描位元組或耗用插槽。以下 DELETE 陳述式的範例涵蓋 _PARTITIONDATE 虛擬欄上篩選器的整個分區:

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

    前往 BigQuery

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

    DELETE mydataset.mytable
    WHERE _PARTITIONDATE IN ('2076-10-07', '2076-03-06');

  3. 按一下 「Run」

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

bq

使用 bq rm 指令並搭配 --table 旗標 (或 -t 捷徑),並指定分區修飾符來刪除特定分區。

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 參數來指定資料表和分區修飾符。

分區資料表安全性

分區資料表的存取權控管與標準資料表的存取權控管相同。詳情請參閱「資料表存取權控管簡介」。