建立 Apache Iceberg 唯讀外部資料表

Apache Iceberg 唯讀外部資料表可讓您以唯讀格式存取 Apache Iceberg 資料表,並提供更精細的存取權控管機制。這項功能與 BigQuery 中的 Apache Iceberg 專用 BigLake 資料表不同,後者可讓您在 BigQuery 中以可寫入格式建立 Iceberg 資料表。

Iceberg 是開放原始碼的資料表格式,可支援 PB 等級的資料表。Iceberg 開放規格可讓您在物件儲存庫中儲存的單一資料副本上執行多個查詢引擎。Apache Iceberg 唯讀外部資料表 (以下稱為 Iceberg 唯讀資料表) 支援 Iceberg 規格第 2 版,包括 merge-on-read。

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

您可以透過下列方式建立 Iceberg 唯讀資料表:

  • 使用 BigLake 元資料庫 (建議用於 Trusted Cloud by S3NS) BigLake 中繼資料庫是以 BigQuery 目錄為基礎,並直接與 BigQuery 整合。BigLake metastore 中的資料表可透過多個開放原始碼引擎變更,且可透過 BigQuery 查詢相同的資料表。BigLake 元資料庫也支援與 Apache Spark 的直接整合。

  • 使用 AWS Glue Data Catalog (AWS 適用,建議使用)AWS Glue 是 AWS 建議的方法,因為它是集中式中繼資料存放區,可讓您定義儲存在各種 AWS 服務中的資料結構和位置,並提供自動結構探索和與 AWS 分析工具整合等功能。

  • 使用 Iceberg JSON 中繼資料檔案 (建議用於 Azure)。如果您使用 Iceberg JSON 中繼資料檔案,則在任何表格更新時,都必須手動更新最新的中繼資料檔案。您可以使用 Apache Spark 的 BigQuery 已儲存程序,建立參照 Iceberg 中繼資料檔案的 Iceberg 唯讀資料表。

如需限制的完整清單,請參閱「限制」一節。

事前準備

必要的角色

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

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

這些預先定義的角色包含建立 Iceberg 唯讀資料表所需的權限。如要查看確切的必要權限,請展開「必要權限」部分:

所需權限

您必須具備下列權限,才能建立 Iceberg 唯讀資料表:

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

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

使用 BigLake metastore 建立資料表

建議您使用 BigLake 中繼資料庫建立 Iceberg 唯讀資料表。您可以使用 Apache Spark 建立這些資料表。使用 BigQuery 預存程序是執行這項操作的便利方式。如需範例,請參閱「建立及執行預存程序」。

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

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

在您使用 Spark 建立 Iceberg 資料表時,系統會在您指定的 Cloud Storage 值區中建立 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 標記,啟用require 分區篩選器

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

    在 Trusted 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. 使用加上 --autodetect_schema 旗標的 bq update 指令

    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 會將 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 唯讀資料表有外部資料表限制和下列限制:

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

    • 每個資料檔案最多可與 10,000 個刪除檔案建立關聯。
    • 刪除檔案最多只能套用 100,000 個相等 ID。
    • 您可以透過經常壓縮刪除的檔案,或是在 Iceberg 資料表上方建立檢視畫面,避免經常變異的分區,來解決這些限制。
  • BigQuery 支援使用所有 Iceberg 區塊轉換函式 (Bucket 除外) 來修剪資訊清單。如要瞭解如何修剪分區,請參閱「查詢分區資料表」。查詢參照 Iceberg 唯讀資料表時,必須在述詞中包含與已分區欄比較的文字常值。

  • 僅支援 Apache Parquet 資料檔案。

合併讀取費用

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

  • 資料檔案中讀取的所有邏輯位元組 (包括依位置和相等性刪除而標示為已刪除的資料列)。
  • 邏輯位元組會讀取載入的刪除相等性和位置刪除檔案,以便在資料檔案中尋找已刪除的資料列。

必須使用分區篩選器

您可以為 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

請使用 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 儲存體。

    • 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

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

  • DATASET:BigQuery 的名稱

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

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

    例如 mytable

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

如果您在建立分區資料表時未啟用「require partition filter」選項,可以更新資料表以新增該選項。

bq

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

例如:

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

bq update --require_partition_filter PROJECT_ID:DATASET.TABLE

後續步驟