建立 Apache Iceberg 外部資料表
Apache Iceberg 外部資料表可讓您以唯讀格式存取 Apache Iceberg 資料表,並提供更精細的存取控管機制,包括資料列層級和資料欄層級安全防護,以及資料遮蓋。在多數用途中,我們不再建議使用這些資料表。請改為參閱「建議的替代方案」。
建議的替代方案
視資料儲存位置而定,建議您採用下列替代方案,存取中繼資料並非由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 外部資料表」。
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) 取得這項權限。瞭解如何授予角色。
如要在 BigQuery 中使用 Spark 預存程序建立 Iceberg 外部資料表,請務必按照下列步驟操作:
如要將 Iceberg 外部資料表中繼資料和資料檔案儲存在 Cloud Storage,請建立 Cloud Storage bucket。您必須連線至 Cloud Storage bucket,才能存取中繼資料檔案。請按照以下步驟操作:
必要的角色
如要取得建立 Iceberg 外部資料表所需的權限,請要求管理員授予您專案的下列 IAM 角色:
- BigQuery 管理員 (
roles/bigquery.admin) - Storage 物件管理員 (
roles/storage.objectAdmin)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
這些預先定義的角色具備建立 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。
- AWS 範例:
CONNECTION_PROJECT_ID:專案,包含用於建立 Iceberg 外部資料表的連線,例如myprojectCONNECTION_REGION:建立 Iceberg 外部資料表時,連線所在的區域,例如usCONNECTION_ID:資料表連結 ID,例如myconnection在 Google Cloud 控制台查看連線詳細資料時,連線 ID 是「Connection ID」(連線 ID) 中顯示的完整連線 ID 最後一個部分的值,例如
projects/myproject/locations/connection_location/connections/myconnectionDATASET:要建立資料表的 BigQuery 資料集名稱例如
mydataset。EXTERNAL_TABLE:要建立的資料表名稱例如
mytable。
可更新資料表中繼資料
如果您使用 JSON 中繼資料檔案建立 Iceberg 外部資料表,請將資料表定義更新為最新的資料表中繼資料。如要更新結構定義或中繼資料檔案,請選取下列其中一個選項:
bq
建立資料表定義檔案:
bq mkdef --source_format=ICEBERG \ "URI" > TABLE_DEFINITION_FILE
使用
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:要更新的資料表所在專案 IDDATASET:資料集,內含要更新的資料表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。
- AWS 範例:
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。
- AWS 範例:
CONNECTION_PROJECT_ID:包含連線的專案,用於建立 Iceberg 外部資料表,例如myprojectCONNECTION_REGION:區域,包含用於建立 Iceberg 外部資料表的連線。例如:us。CONNECTION_ID:連線 ID。例如:myconnection。在 Google Cloud 控制台查看連線詳細資料時,連線 ID 是「Connection ID」(連線 ID) 中顯示的完整連線 ID 最後一個部分的值,例如
projects/myproject/locations/connection_location/connections/myconnectionDATASET:BigQuery 資料表的名稱資料集。例如
mydataset。EXTERNAL_TABLE:要建立的資料表名稱例如
mytable。
您也可以更新 Iceberg 資料表,啟用必要的分區篩選器。
如果在建立分區資料表時未啟用「必須使用分區篩選器」選項,可以更新資料表來新增該選項。
bq
使用 bq update 指令並提供 --require_partition_filter 旗標。
例如:
如要在預設專案中更新 mydataset 中的 mypartitionedtable,請輸入:
bq update --require_partition_filter PROJECT_ID:DATASET.TABLE
後續步驟
- 瞭解 Spark 預存程序。
- 瞭解存取控管政策。
- 瞭解如何在 BigQuery 中執行查詢。
- 瞭解 BigQuery 支援的陳述式和 SQL 方言。