存放區的最佳做法

本文提供以下有關資料表單存放區的資訊:

Dataform 存放區最佳做法總覽

本節將概略說明在 Dataform 中管理存放區大小、存放區結構和程式碼生命週期的最佳做法。

存放區大小的最佳做法

存放區大小會影響 Dataform 的多個開發層面,例如:

  • 協同合作
  • 程式碼集可讀性
  • 開發程序
  • 工作流程編譯
  • 工作流程執行作業

Dataform 會強制執行API 配額和編譯資源限制。大型存放區可能會導致存放區超出這些配額和限制。這可能導致工作流程編譯和執行失敗。

為降低風險,建議您分割大型存放區。拆分大型存放區時,您會將大型工作流程拆分為多個較小的工作流程,這些工作流程會儲存在不同的存放區中,並透過跨存放區依附元件連結在一起。

這個方法可讓您遵守 Dataform 配額和限制、實作精細的程序和權限,以及改善程式碼庫的可讀性和協作功能。不過,管理分割的存放區比管理單一存放區更具挑戰性。

如要進一步瞭解 Dataform 中存放區大小的影響,請參閱「存放區大小總覽」。如要進一步瞭解分割存放區的最佳做法,請參閱「分割存放區」。

存放區結構的最佳做法

建議您在 definitions 目錄中建立檔案結構,以反映工作流程的階段。請注意,您可以採用最符合需求的自訂結構。

以下是建議的 definitions 子目錄結構,反映大多數工作流程的重要階段:

  • sources:用於儲存資料來源宣告。
  • intermediate,用於儲存資料轉換邏輯。
  • output,用於儲存輸出資料表的定義。
  • extras (選用):用於儲存其他檔案。

Dataform 中的所有檔案名稱都必須符合 BigQuery 資料表命名規範。建議您在 Dataform 存放區的 definitions 目錄中,使用反映子目錄結構的檔案名稱。

如要進一步瞭解如何在存放區中建立檔案結構及命名檔案的最佳做法,請參閱「在存放區中建構程式碼」。

程式碼生命週期的最佳做法

Dataform 中的預設程式碼生命週期包含以下階段:

如要管理 Dataform 中的程式碼生命週期,您可以建立執行環境,例如開發、測試和正式環境。

如要進一步瞭解 Dataform 中的程式碼生命週期,請參閱「Dataform 中的程式碼生命週期簡介」。

您可以選擇將執行環境保留在單一存放區,或多個存放區。

單一存放區中的執行環境

您可以使用工作區編譯覆寫功能發布版本設定,在單一 Dataform 存放區中建立獨立的執行環境,例如開發、測試和實際工作環境。

您可以透過下列方式建立隔離的執行環境:

  • 依據結構定義將開發和實際工作環境的資料表分開。
  • 依據結構定義和 Google Cloud 專案,將開發環境和實際工作環境的資料表分開。
  • 依 Google Cloud 專案將開發、測試和實際工作環境資料表分開。

接著,您可以使用工作流程設定,在測試和正式環境中安排執行作業。建議您在開發環境中手動觸發執行作業。

如要進一步瞭解在 Dataform 中管理程式碼生命週期的最佳做法,請參閱「管理程式碼生命週期」。

多個存放區中的程式碼生命週期

如要針對程式碼生命週期的各個階段自訂身分和存取管理權限,您可以建立多個存放區副本,並儲存在不同的 Google Cloud 專案中。

每個 Google Cloud 專案都會做為執行環境,對應至程式碼生命週期階段,例如開發和正式版。

在這種做法中,我們建議在所有專案中維持相同的存放區程式碼集。如要在存放區的每個副本中自訂編譯和執行作業,請使用工作區編譯覆寫設定版本設定工作流程設定

存放區大小總覽

本節將說明存放區大小如何影響工作流程開發和 Dataform 編譯資源用量,以及如何估算存放區的編譯資源用量。

關於 Dataform 中的存放區大小

存放區的大小會影響 Dataform 開發作業的下列層面:

  • 協同合作:在大型存放區中工作的多位協作者可能會產生過多提取要求,進而增加合併衝突的風險。

  • 程式碼集可讀性。在單一存放區中,如果有大量檔案組成工作流程,可能會導致存放區難以瀏覽。

  • 開發程序。單一存放區中大型工作流程的部分區域可能需要自訂權限或程序 (例如排程),這些權限或程序與套用於工作流程其餘部分的權限或程序不同。存放區大小過大,因此很難針對工作流程的特定領域調整開發程序。

  • 工作流程編譯。Dataform 會強制套用編譯資源的用量限制。大型存放區可能會超過這些限制,導致編譯作業失敗。

  • 工作流程執行作業。執行期間,Dataform 會在工作區中執行存放區程式碼,並將資產部署至 BigQuery。存放區越大,Dataform 執行的時間就越長。

如果存放區的大小會對 Dataform 中的開發作業造成負面影響,您可以將存放區分割成多個較小的存放區。

關於存放區編譯資源限制

在開發期間,Dataform 會編譯工作區中的所有存放區程式碼,以產生存放區中工作流程的表示法。這就是所謂的「編譯結果」。Dataform 會對編譯資源強制執行用量限制。

您的存放區可能會因為下列原因而超過用量限制:

  • 存放區程式碼中出現無限迴圈錯誤。
  • 存放區程式碼中的記憶體流失錯誤。
  • 大型存放區,大約超過 1000 個工作流程動作。

如要進一步瞭解編譯資源的使用限制,請參閱「Dataform 編譯資源限制」。

預估存放區的編譯資源用量

您可以預估存放區的下列編譯資源使用量:

  • CPU 時間用量。
  • 在您的存放區中定義的動作所產生圖表的序列化資料總大小上限。

如要粗略估算存放區編譯作業目前的 CPU 時間用量,您可以在本機 Linux 或 macOS 機器上計時,測量 Dataform 工作流程的編譯作業時間。

  • 如要計時編譯工作流程,請在存放區中以以下格式執行 Dataform CLI 指令 dataform compile

    time dataform compile
    

    以下程式碼範例顯示執行 time dataform compile 指令的結果:

    real    0m3.480s
    user    0m1.828s
    sys     0m0.260s
    

您可以將 real 結果視為大致的指標,用來瞭解存放區編譯作業的 CPU 時間用量。

如要大致瞭解已在存放區中產生的動作圖表的總大小,您可以將圖表的輸出內容寫入 JSON 檔案。您可以將未壓縮的 JSON 檔案大小視為總圖表大小的粗略指標。

  • 如要將工作流程的已編譯圖表輸出內容寫入 JSON 檔案,請在存放區中執行下列 Dataform CLI 指令:

    dataform compile --json > graph.json
    

分割存放區

本節將說明分割 Dataform 存放區和管理跨存放區依附元件的策略。

存放區是 Dataform 中的核心單元。存放區會儲存組成工作流程的所有 SQLX 和 JavaScript 檔案,以及 Dataform 設定檔和套件。您可以將工作流程儲存在單一存放區,也可以將工作流程拆分至多個存放區。

在 Dataform 中分割存放區有以下優點:

  • 遵守 Dataform 對編譯資源使用量的限制。將大型工作流程拆分為多個較小的存放區,可降低超出 Dataform 編譯資源限制的風險。
  • 精細處理程序。您可以為工作流程的每個分割片段和開發團隊個別設定流程,例如持續整合 (CI) 規則。
  • 精細權限。您可以為工作流程的每個分割片段和開發團隊個別設定權限,藉此提升工作流程的整體安全性。
  • 盡量減少在工作流程的每個分割片段中工作的協作者人數,藉此改善協作作業。
  • 改善程式碼集的可讀性。將組成大型工作流程的檔案分割成多個存放區,比起一次瀏覽整個工作流程,更容易個別瀏覽每個存放區。
  • 與執行整個工作流程相比,加快工作流程的每個分割片段執行速度。

在 Dataform 中分割存放區會帶來以下缺點:

  • 每個 Dataform 存放區及其對應的 Git 存放區都需要自訂持續整合和持續開發 (CI/CD) 設定。
  • 每個 Dataform 存放區及其對應的 Git 存放區都需要自訂排程設定。
  • 在多個存放區中,工作流程物件之間的依附元件難以管理。
  • 缺乏完整的有向非循環圖 (DAG) 視覺化,無法呈現多個存放區之間的 SQL 工作流程。在每個存放區中,產生的 DAG 只代表完整工作流程的一部分。

分割存放區的策略

分割存放區時,您會將組成父項 SQL 工作流程的檔案,分割為個別 Dataform 存放區中儲存的較小子項工作流程。

您可以選擇下列任一方式分割存放區:

  • 每個開發團隊一個存放區。
  • 每個領域一個存放區,例如銷售、行銷或物流。
  • 每個網域各有一個集中式存放區和一個存放區,並使用集中式存放區的內容做為資料來源。

如要在第三方 Git 代管平台中安置父項工作流程,您需要將包含子項工作流程的各個個別存放區個別連結至專屬的第三方 Git 存放區。

管理跨儲存庫依附元件

分割存放區最有效率的方式,就是將父項 SQL 工作流程劃分為獨立的子項工作流程,建立獨立的存放區。獨立存放區不會使用其他存放區的內容做為資料來源。這種做法不需要管理跨儲存庫的依附元件。

如果無法避免跨存放區的依附元件,您可以將存放區分割為一系列的存放區,其中一個存放區會依附先前的存放區,並成為後續存放區的資料來源。存放區和依附元件的繼承順序必須最能反映父項工作流程的結構。

您可以使用 Dataform 資料來源宣告,在存放區之間建立依附元件。您可以從其他 Dataform 存放區宣告 BigQuery 表格類型,做為要編輯的存放區中的資料來源。宣告資料來源後,您可以像任何其他 Dataform 工作流程動作一樣參照該資料來源,並用於開發工作流程。

當您排定在含有跨儲存庫相依性的儲存庫之間執行工作流程分割作業時,必須依照跨儲存庫相依性的順序逐一執行儲存庫。

建議您不要將存放區拆分為一組具有雙向依附元件的存放區。如果某個存放區是其他存放區的資料來源,同時也使用該存放區做為資料來源,就會發生存放區之間的雙向依附元件。存放區之間的雙向依附元件會使父項工作流程的排程和執行作業,以及開發程序變得複雜。

在存放區中結構化程式碼

本節將說明在 Dataform 存放區的根目錄 definitions 中,建構及命名工作流程檔案的最佳做法。definitions 目錄的建議結構反映了工作流程的階段。您可以採用任何符合業務需求的結構。

您可能會基於以下原因,在 definitions 目錄中建構工作流程程式碼:

  • 指定團隊負責工作流程的特定部分,改善程式碼集的協作作業。
  • 在組織變更時,改善工作流程的可維護性。
  • 改善程式碼庫的導覽功能。
  • 改善程式碼集的擴充性。
  • 盡量減少團隊的行政負擔。

Dataform 存放區中的根目錄 definitions 包含建立工作流程元素的程式碼。您可以將 definitions 目錄中的檔案整理成反映工作流程結構的目錄結構。

開發工作流程時,您會宣告來源表格並轉換為輸出表格,以便用於業務或分析用途。

您可以區分工作流程的三個主要階段:

  1. 宣告資料來源。
  2. 來源資料的轉換。
  3. 定義從經過轉換的來源資料產生的輸出表格。

以下是 definitions 目錄中子目錄的結構,反映了工作流程的主要階段:

sources
資料來源宣告和來源資料的基本轉換作業,例如篩選。
intermediate
資料表和動作會從 sources 讀取資料並轉換資料,然後再使用轉換後的資料定義 outputs 資料表。在 Dataform 將資料表執行至 BigQuery 後,通常不會將資料表公開給其他程序或工具 (例如商業智慧 (BI) 工具)。
outputs
Dataform 在 BigQuery 中執行後,由程序或工具 (例如商業智慧) 用來消耗的資料表定義。
extra
工作流程主要管道以外的檔案,例如包含工作流程資料的檔案,這些資料可用於其他用途,例如機器學習。自訂的選用子目錄。

sources最佳做法

sources 子目錄包含工作流程的第一個階段:宣告和基本轉換來源資料。

sources 子目錄中,儲存用於篩選、分類、轉換或重新命名資料欄的資料來源宣告和資料表。

避免儲存結合多個來源資料的資料表。

轉換儲存在 intermediate 子目錄中的資料表中的 sources 資料。

如果您要宣告多個集區的資料來源 (例如 Google Ads 或 Google Analytics),請為每個集區專用一個子目錄。

以下範例顯示 sources 的子目錄結構,其中包含兩個來源集區:

definitions/
    sources/
        google_ads/
            google_ads_filtered.sqlx
            google_ads_criteria_metrics.sqlx
            google_ads_criteria_metrics_filtered.sqlx
            google_ads_labels.sqlx
            google_ads_labels_filtered.sqlx
        google_analytics/
            google_analytics_users.sqlx
            google_analytics_users_filtered.sqlx
            google_analytics_sessions.sqlx

如果您在同一個結構定義中宣告多個資料來源資料表,可以將這些宣告合併至單一 JavaScript 檔案。

如要進一步瞭解如何使用 JavaScript 建立資料來源宣告,請參閱「使用 JavaScript 建立 Dataform 工作流程」一文。

以下程式碼範例顯示單一 JavaScript 檔案中宣告的單一結構定義中的多個資料來源:

[
  "source_table_1",
  "source_table_2",
  "source_table_3"
].forEach((name) =>
  declare({
    database: "gcp_project",
    schema: "source_dataset",
    name,
  })
);

為避免工作流程受到資料來源變更的影響,您可以為每個資料來源宣告建立檢視畫面,例如 analytics_users_filtered.sqlx。檢視畫面可包含來源資料的基本篩選和格式設定。將檢視畫面儲存在 sources 子目錄中。

接著,在建立 intermediateoutputs 資料表時,請參照檢視表,而非原始來源資料表。這種做法可讓您測試來源資料表。如果來源資料表有所變更,您可以修改資料檢視畫面,例如新增篩選器或重新計算資料。

intermediate最佳做法

intermediate 子目錄包含工作流程的第二階段:從一或多個來源轉換及匯總來源資料。

intermediate 子目錄中,儲存可大幅轉換 sources 子目錄中一或多個來源來源資料的檔案,例如彙整資料的資料表。intermediate 子目錄中的資料表通常會查詢來源資料表或其他 intermediate 資料表的資料。

使用 intermediate 資料表建立 outputs 資料表。通常,在 Dataform 將 intermediate 資料表執行至 BigQuery 後,就不會用於其他用途 (例如資料分析)。您可以將 intermediate 資料表視為可建立輸出資料表的資料轉換邏輯。

建議您記錄測試所有 intermediate 資料表。

outputs最佳做法

outputs 子目錄包含工作流程的最後階段:從轉換後的資料建立輸出表格,以供業務用途。

outputs 目錄中,儲存您打算在 Dataform 將資料執行至 BigQuery 後,用於其他程序或工具的資料表,例如報表或資訊主頁。outputs 目錄中的資料表通常會查詢 intermediate 資料表中的資料。

依據相關的業務實體將 outputs 資料表分組,例如行銷、訂單或數據分析。為每個業務實體專屬一個子目錄。

如要將輸出資料表分別儲存在 BigQuery 中,您可以為輸出資料表設定專屬的結構定義。如需設定資料表結構定義的操作說明,請參閱「覆寫資料表設定」。

以下範例顯示 outputs 的子目錄結構,其中包含 salesmarketing 業務實體:

definitions/
    outputs/
        orders/
            orders.sqlx
            returns.sqlx
        sales/
            sales.sqlx
            revenue.sqlx
        marketing/
            campaigns.sqlx

建議您記錄測試所有 outputs 資料表。

命名策略

Dataform 中的所有檔案名稱都必須符合 BigQuery 資料表命名規範

建議您在 Dataform 存放區的 definitions 目錄中,使用反映子目錄結構的檔案名稱。

sources 子目錄中,檔案名稱應指向與檔案相關的來源。將來源名稱新增為檔案名稱的前置字串,例如 analytics_filtered.sqlx

intermediate 子目錄中,檔案名稱應標示子目錄,方便協作者清楚區分 intermediate 檔案。選取專屬的前置字串,並只套用至 intermediate 目錄中的檔案,例如 stg_ads_concept.sqlx

outputs 子目錄中,檔案名稱應簡明扼要,例如 orders.sqlx。如果您在不同實體子目錄中擁有名稱相同的 outputs 資料表,請新增可識別實體的前置字串,例如 sales_revenue.sqlxads_revenue.sqlx

以下範例顯示 definitions 目錄內的子目錄結構,其中檔案名稱符合建議的命名策略:

definitions/
    sources/
        google_analytics.sqlx
        google_analytics_filtered.sqlx
    intermediate/
        stg_analytics_concept.sqlx
    outputs/
        customers.sqlx
        sales/
            sales.sqlx
            sales_revenue.sqlx
        ads/
            campaigns.sqlx
            ads_revenue.sqlx

後續步驟