如何設計受治理的指標語意層?
題幹與適用場景
公司發現「活躍客戶」「收入」與「留存率」在不同報表中的 SQL 不一致。請設計語意層,讓 BI、Notebook、API 與後續自動化代理共用指標定義。需要支援維度、時間粒度、篩選器、權限、歷史版本與近即時資料,並說明如何避免語意層變成另一個不可測試的報表平台。
面試官考察點
強回答先區分實體、維度、度量、聚合與指標語意,再處理 join 粒度、重複計數、時區與遲到資料。面試官期待把指標當作版本化產品契約:定義、所有者、來源、適用粒度、品質狀態與相容性都可稽核,而不是只提供 SQL 模板目錄。
回答前需要釐清的問題
- 指標的事實粒度是什麼?訂單、訂單行與事件混用會造成收入重複聚合。
- 使用者需要哪些維度與時間粒度?並非所有組合都能安全計算,需宣告支援矩陣。
- 資料新鮮度與一致性目標是什麼?即時、日批與回補資料的可見狀態不同。
- 誰能發布定義、誰能讀取敏感維度?指標權限不能繞過底層行列級安全。
- 需要回溯歷史口徑還是只看目前口徑?答案決定版本路由、快照與重算成本。
推薦方案與推導
建立不可變的指標定義實體:名稱、描述、measure 表達式、預設聚合、維度、時間語意、篩選器、資料源、負責人、版本、狀態與品質 SLO。查詢只引用 metric ID、維度與時間窗口,編譯器負責產生 SQL 或下推預聚合表。
編譯前做語意檢查:驗證 join 路徑唯一、聚合與粒度匹配、篩選器可否下推、使用者是否擁有欄位權限。對 count distinct、比率與窗口指標記錄分母、去重鍵和空值策略,禁止不同工具各自猜測。
metric: active_customers
version: 3
owner: growth-data
source: mart_customer_daily
measure: count_distinct(customer_id)
dimensions: [plan, region]
time_grain: [day, week, month]
freshness_slo: 2h
status: published採雙軌發布:新版本先在影子查詢與舊版本比較,再開放少量工作區;差異超過閾值就自動阻斷升級。快取鍵必須包含 metric version、維度、篩選器與資料水位,否則切換版本會讀到舊結果。高成本查詢設定預算、逾時與預聚合回退。
替代方案與取捨
將邏輯放在各 BI 工具上線快,但定義會分叉;只建一個物理資料集簡單,卻無法表達多粒度與權限。集中語意層提供一致性和可重用 API,代價是編譯器、版本治理、權限映射與排錯能力。小團隊可先從少量核心指標與一個消費端開始,再開放多工具接入。
失敗場景、邊界與反例
- 把「收入」定義成簡單
sum(amount),忽略退款、稅、幣種與訂單重複 join。 - 允許指標定義直接讀任意原始表,繞過品質閘門與欄位權限。
- 修改指標含義卻不升版本,歷史儀表板悄悄改變結果。
- 用快取命中率證明正確性,忽略資料水位、遲到事件與回補期間的可見狀態。
- 為支援所有維度組合產生笛卡爾積查詢,導致成本與延遲失控;應公開不支援組合並提供替代聚合。
測試與驗證清單
每個指標保存黃金查詢與小型固定資料集,驗證聚合、分母、時區、空值、重複 join、遲到事件與版本差異。做 schema、權限、編譯器與快取契約測試;用生產樣本進行結果對比與成本回歸。發布閘門至少檢查定義完整、來源新鮮、品質 SLO 達標、權限映射存在與新舊版本差異在閾值內。
追問與延伸
如何處理指標定義的破壞性變更?
發布新版本並保留舊版本路由,標記棄用時間,通知依賴者,遷移後再刪除。歷史報告必須能指定舊版本重算,不能復用版本號。
語意層如何支援近即時與批處理?
定義宣告來源與資料水位,查詢結果攜帶 freshness 和 completeness 狀態。近即時源可先給暫時結果,批處理完成後校準;兩者必須共用相同語意與去重規則。
如何限制自然語言或自動化代理誤用指標?
只暴露已發布指標、支援維度與權限範圍,回傳可解釋查詢計畫與定義版本。拒絕無法證明粒度、權限或新鮮度的請求,不讓模型自由拼接原始表 SQL。