建立 Apache Iceberg 外部資料表

Apache Iceberg 外部資料表可讓您以唯讀格式存取 Apache Iceberg 資料表,並提供更精細的存取控管機制,包括資料列層級和資料欄層級安全防護,以及資料遮蓋。在多數用途中,我們不再建議使用這些資料表。請改為參閱「建議的替代方案」。

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

Iceberg 格式和版本支援

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

事前準備

啟用 BigQuery Connection 和 BigQuery Reservation API (如果尚未啟用)。

啟用 API 所需的角色

您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「Service Usage 管理員」角色 (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 Storage。

    • 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 是「Connection 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 外部資料表的存取權。

BigQuery 管理員可以強制執行資料列和資料欄層級的存取控管,包括資料表的資料遮蓋。在 Managed Service for Apache Spark 和 Serverless Spark 中,如果使用 BigQuery Storage API 做為資料表的資料來源,系統也會強制執行資料表存取政策。

查詢 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 等錯誤。

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

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

  • 僅支援 Apache Parquet 資料檔案。

  • 彈性設定資料欄名稱:

    • 如果 Iceberg 外部資料表是根據含有非英數字元的資料欄分區,BigQuery 可能無法從資訊清單擷取分區中繼資料,導致系統執行完整資料表掃描。
    • BigQuery 無法直接查詢含有結構字元 (例如點 .、錢幣符號 $、括號 []、圓括號 () 或斜線 /) 的 Iceberg 資料表。如果工作流程需要在 Lakehouse 執行階段目錄或目錄服務中註冊這類資料表,以便專門用於外部引擎 (例如 Spark 或 Trino),請與 Cloud Customer Care 聯絡,要求在專案層級啟用。
  • 不支援下列 Iceberg 第 3 版功能:

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

讀取時合併費用

讀取時合併資料的隨選計費,是下列資料的掃描總和:

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

必須使用分區篩選器

您可以為 Iceberg 資料表啟用「必須使用分區篩選器」選項,強制使用述詞篩選器。如果啟用這個選項,在嘗試查詢資料表時,若未指定與各資訊清單檔案一致的 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 Storage。

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

bq

使用 bq mk --table 指令和 @connection 裝飾器,在 --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 Storage。

    • 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 是「Connection 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

後續步驟