建立 Apache Iceberg 外部資料表

您可以使用 Apache Iceberg 外部資料表,以唯讀格式存取 Apache Iceberg 資料表,並導入精細的存取控管機制。在多數情況下,我們不再建議使用這些表格。 請改為參閱「建議替代方案」。

Iceberg 是開放原始碼資料表格式,支援 PB 級資料表。Iceberg 開放規格可讓您在物件儲存空間中儲存的單一資料副本上,執行多個查詢引擎。Apache Iceberg 外部資料表 (以下簡稱 Iceberg 外部資料表) 支援 Iceberg 第 2 版,包括讀取時合併。支援 Iceberg 第 3 版, 包括二進位刪除向量,目前為預先發布版。 如要提供意見回饋或提出與這項預先發布版功能相關的問題,請傳送電子郵件至 biglake-help@google.com

BigQuery 管理員可以強制執行列層級和欄層級的存取控管,包括資料表上的資料遮蓋。如要瞭解如何在資料表層級設定存取控管,請參閱「設定存取控管政策」。當您使用 BigQuery Storage API 做為 Managed Service for Apache Spark 和 Serverless Spark 中資料表的資料來源時,系統也會強制執行資料表存取政策。

視資料儲存位置而定,我們建議使用下列替代方案,存取中繼資料並非由Google Cloud管理的 Iceberg 資料表:

  • 由遠端目錄 (例如 AWS Glue、Databricks Unity Catalog 和 Snowflake Horizon Catalog) 管理的 Cloud Storage 或 Amazon Simple Storage Service (Amazon S3) 資料。使用Lakehouse 執行階段目錄存取跨雲端資料。Lakehouse 執行階段目錄的跨雲端資料存取功能可讓您直接從 Google Cloud 查詢其他雲端供應商的資料,不必遷移檔案或建構複雜的 ETL 管道。
  • Azure Blob 儲存體或 Apache Iceberg 資料表並非由支援的遠端目錄管理,因此無法透過 Lakehouse 執行階段目錄存取跨雲端資料。請繼續瞭解如何使用 Iceberg JSON 中繼資料檔案建立 Apache Iceberg 外部資料表

事前準備

啟用 BigQuery Connection 和 BigQuery Reservation API。

啟用 API 時所需的角色

如要啟用 API,您必須具備 serviceusage.services.enable 權限。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

啟用 API

必要的角色

如要取得建立 Iceberg 外部資料表所需的權限,請要求管理員授予您專案的下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

這些預先定義的角色具備建立 Iceberg 外部資料表所需的權限。如要查看確切的必要權限,請展開「Required permissions」(必要權限) 部分:

所需權限

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

  • bigquery.tables.create
  • bigquery.connections.delegate
  • bigquery.jobs.create

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

使用中繼資料檔案建立資料表

您可以使用 JSON 中繼資料檔案建立 Iceberg 外部資料表。不過,您必須手動更新 JSON 中繼資料檔案的 URI,才能讓 Iceberg 外部資料表保持最新狀態。如果 URI 未保持最新狀態,BigQuery 中的查詢可能會失敗,或提供與直接使用 Iceberg 目錄的其他查詢引擎不同的結果。

使用 Spark 建立 Iceberg 資料表時,系統會在您指定的 Cloud Storage bucket 中建立 Iceberg 資料表的中繼資料檔案。

選取下列選項之一:

SQL

使用 CREATE EXTERNAL TABLE 陳述式。以下範例會建立名為 myexternal-table 的 Iceberg 外部資料表:

  CREATE EXTERNAL TABLE myexternal-table
  WITH CONNECTION `myproject.us.myconnection`
  OPTIONS (
         format = 'ICEBERG',
         uris = ["gs://mybucket/mydata/mytable/metadata/iceberg.metadata.json"]
   )

uris 值替換為特定資料表快照的最新 JSON 中繼資料檔案

您可以設定 require_partition_filter 旗標,啟用「必須使用分區篩選器」

bq

在指令列環境中,使用 bq mk --table 指令@connection 修飾符,在 --external_table_definition 參數結尾指定要使用的連線。 如要啟用必要分區篩選器,請使用 --require_partition_filter

bq mk 
--table
--external_table_definition=TABLE_FORMAT=URI@projects/CONNECTION_PROJECT_ID/locations/CONNECTION_REGION/connections/CONNECTION_ID
PROJECT_ID:DATASET.EXTERNAL_TABLE

更改下列內容:

  • TABLE_FORMAT:要建立的資料表格式

    在本例中為 ICEBERG

  • URI:特定資料表快照的最新 JSON 中繼資料檔案

    例如 gs://mybucket/mydata/mytable/metadata/iceberg.metadata.json

    URI 也可以指向外部雲端位置,例如 Amazon S3 或 Azure Blob 儲存體。

    • AWS 範例:s3://mybucket/iceberg/metadata/1234.metadata.json
    • Azure 範例:azure://mystorageaccount.blob.core.windows.net/mycontainer/iceberg/metadata/1234.metadata.json
  • CONNECTION_PROJECT_ID:包含連線的專案,用於建立 Iceberg 外部資料表,例如 myproject

  • CONNECTION_REGION:包含要建立 Iceberg 外部資料表連線的區域,例如 us

  • CONNECTION_ID:資料表連線 ID,例如 myconnection

    在 Google Cloud 控制台中查看連線詳細資料時,連線 ID 是「連線 ID」中顯示的完整連線 ID 最後一個部分的值,例如:projects/myproject/locations/connection_location/connections/myconnection

  • DATASET:您要在其中建立資料表的 BigQuery 資料集名稱

    例如 mydataset

  • EXTERNAL_TABLE:要建立的資料表名稱

    例如 mytable

可更新資料表中繼資料

如果您使用 JSON 中繼資料檔案建立 Iceberg 外部資料表,請將資料表定義更新為最新的資料表中繼資料。如要更新結構定義或中繼資料檔案,請選取下列任一選項:

bq

  1. 建立資料表定義檔:

    bq mkdef --source_format=ICEBERG \
    "URI" > TABLE_DEFINITION_FILE
    
  2. 使用 bq update 指令並加上 --autodetect_schema 旗標:

    bq update --autodetect_schema --external_table_definition=TABLE_DEFINITION_FILE
    PROJECT_ID:DATASET.TABLE
    

    更改下列內容:

    • URI:您的 Cloud Storage URI,其中包含最新的 JSON 中繼資料檔案

      例如 gs://mybucket/us/iceberg/mytable/metadata/1234.metadata.json

    • TABLE_DEFINITION_FILE:包含資料表結構定義的檔案名稱

    • PROJECT_ID:包含要更新資料表的專案 ID

    • DATASET:包含要更新資料表的資料集

    • TABLE:要更新的資料表

API

使用 tables.patch 方法,並將 autodetect_schema 屬性設為 true

PATCH https://bigquery.googleapis.com/bigquery/v2/projects/PROJECT_ID/datasets/DATASET/tables/TABLE?autodetect_schema=true

更改下列內容:

  • PROJECT_ID:包含要更新資料表的專案 ID
  • DATASET:包含要更新資料表的資料集
  • TABLE:要更新的資料表

在要求主體中,為下列欄位指定更新的值:

{
     "externalDataConfiguration": {
      "sourceFormat": "ICEBERG",
      "sourceUris": [
        "URI"
      ]
    },
    "schema": null
  }'

URI 替換為最新的 Iceberg 中繼資料檔案。例如:gs://mybucket/us/iceberg/mytable/metadata/1234.metadata.json

設定存取控管政策

您可以透過資料欄層級安全防護資料列層級安全防護資料遮蓋,控管 Iceberg 外部資料表的存取權。

查詢 Iceberg 外部資料表

詳情請參閱「查詢 Iceberg 資料」。

查詢歷來資料

您可以使用 FOR SYSTEM_TIME AS OF 子句,存取 Iceberg 中繼資料中保留的 Iceberg 外部資料表快照。

任何外部資料表都不支援時空旅行和容錯資料保留期限

資料對應

BigQuery 會將 Iceberg 資料類型轉換為 BigQuery 資料類型,如下表所示:

Iceberg 資料類型 BigQuery 資料類型
boolean BOOL
int INT64
long INT64
float FLOAT64
double FLOAT64
Decimal(P/S) NUMERIC or BIG_NUMERIC depending on precision
date DATE
time TIME
timestamp DATETIME
timestamptz TIMESTAMP
string STRING
uuid BYTES
fixed(L) BYTES
binary BYTES
list<Type> ARRAY<Type>
struct STRUCT
map<KeyType, ValueType> ARRAY<Struct<key KeyType, value ValueType>>

限制

除了外部資料表限制外,Iceberg 外部資料表還有下列限制:

  • 系統不支援使用 VPC Service Controls 的查詢,因此會產生 NO_MATCHING_ACCESS_LEVEL 等錯誤。

  • 使用讀取時合併的資料表有下列限制:

    • 查詢最多可處理表格中總共 10 萬個刪除向量項目。如果是使用二進位刪除向量的 Iceberg 第 3 版資料表,與刪除向量相關聯的每個資料檔案都會計為一個刪除項目,並計入這個限制。
    • 每個資料檔案最多可與 10,000 個刪除檔案建立關聯。
    • 每個資料檔案最多可套用 10 萬次等值刪除作業。
    • 如要解決這些限制,可以經常壓縮刪除檔案和刪除向量,在 Iceberg 資料表上建立檢視區塊,避免經常變動的分區,或根據分區欄篩選查詢,減少掃描的資料檔案和刪除向量數量。
  • BigQuery 支援使用所有 Iceberg 分區轉換函式修剪資訊清單。如要瞭解如何修剪分區,請參閱「查詢分區資料表」。參照 Iceberg 外部資料表的查詢,必須在與分區資料欄比較的述詞中包含常值。

  • 系統僅支援 Apache Parquet 資料檔案。

  • 系統不支援下列 Iceberg 3 版功能:

    • 新資料類型:奈秒時間戳記(時區)、不明、變數、幾何、地理位置
    • 初始預設值
    • 表格加密金鑰

讀取時合併的費用

以量計價的讀取時合併資料費用,是下列資料掃描量的總和:

  • 資料檔案中讀取的所有邏輯位元組 (包括標示為依位置刪除和等值刪除的資料列)。
  • 載入等式刪除、位置刪除和刪除向量檔案時讀取的邏輯位元組,用於尋找資料檔案中已刪除的資料列。

必須使用分區篩選器

您可以為 Iceberg 資料表啟用「require partition filter」(需要分區篩選器) 選項,要求使用述詞篩選器。啟用此選項後,如嘗試查詢資料表,但未指定與每個資訊清單檔案一致的 WHERE 子句,系統會產生下列錯誤:

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

每個資訊清單檔案至少需要一個適合用於分區排除的述詞。

建立 Iceberg 資料表時,可以透過下列方式啟用 require_partition_filter

SQL

使用 CREATE EXTERNAL TABLE 陳述式。下列範例會建立名為 TABLE 的 Iceberg 外部資料表,並啟用必要的分區篩選器:

  CREATE EXTERNAL TABLE TABLE
  WITH CONNECTION `PROJECT_ID.REGION.CONNECTION_ID`
  OPTIONS (
         format = 'ICEBERG',
         uris = [URI],
         require_partition_filter = true
   )

更改下列內容:

  • TABLE:要建立的資料表名稱。
  • PROJECT_ID:包含要建立資料表的專案 ID。
  • REGION:要建立 Iceberg 資料表的位置
  • CONNECTION_ID連線 ID。例如:myconnection

  • URI:包含最新 JSON 中繼資料檔案的 Cloud Storage URI。

    例如 gs://mybucket/us/iceberg/mytable/metadata/1234.metadata.json

    URI 也可以指向外部雲端位置,例如 Amazon S3 或 Azure Blob 儲存體。

    • AWS 範例:s3://mybucket/iceberg/metadata/1234.metadata.json
    • Azure 範例:azure://mystorageaccount.blob.core.windows.net/mycontainer/iceberg/metadata/1234.metadata.json

bq

使用 @connection 裝飾器搭配 bq mk --table 指令,在 --external_table_definition 參數結尾指定要使用的連線。 使用 --require_partition_filter 啟用必要分區篩選器。 下列範例會建立名為 TABLE 的 Iceberg 外部資料表,並啟用「需要分區篩選器」:

bq mk \
    --table \
    --external_table_definition=ICEBERG=URI@projects/CONNECTION_PROJECT_ID/locations/CONNECTION_REGION/connections/CONNECTION_ID \
    PROJECT_ID:DATASET.EXTERNAL_TABLE \
    --require_partition_filter

更改下列內容:

  • URI:特定資料表快照的最新 JSON 中繼資料檔案

    例如 gs://mybucket/mydata/mytable/metadata/iceberg.metadata.json

    URI 也可以指向外部雲端位置,例如 Amazon S3 或 Azure Blob 儲存體。

    • AWS 範例:s3://mybucket/iceberg/metadata/1234.metadata.json
    • Azure 範例:azure://mystorageaccount.blob.core.windows.net/mycontainer/iceberg/metadata/1234.metadata.json
  • CONNECTION_PROJECT_ID:包含要建立 Iceberg 外部資料表之連線的專案,例如 myproject

  • CONNECTION_REGION:包含連線的區域,用於建立 Iceberg 外部資料表。例如:us

  • CONNECTION_ID連線 ID。例如:myconnection

    在 Google Cloud 控制台中查看連線詳細資料時,連線 ID 是「連線 ID」中顯示的完整連線 ID 最後一個部分的值,例如:projects/myproject/locations/connection_location/connections/myconnection

  • DATASET:BigQuery 的名稱

    包含要更新資料表的資料集。例如 mydataset

  • EXTERNAL_TABLE:要建立的資料表名稱

    例如 mytable

您也可以更新 Iceberg 資料表,啟用必要分區篩選器。

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

bq

使用 bq update 指令並加上 --require_partition_filter 旗標。

例如:

如要在預設專案中更新 mydataset 中的 mypartitionedtable,請輸入:

bq update --require_partition_filter PROJECT_ID:DATASET.TABLE

後續步驟