← 返回首頁
Firebase
Firebase
@Firebase
85🔁 18
𝕏 (Twitter)🔥🔥🔥
AI 中文摘要Claude 生成

Firebase Data Connect 新增原生 SQL 支援

Firebase 正式推出「原生 SQL」功能,讓開發者在 Data Connect 中直接執行原始 SQL 語句,同時保留 Firebase 整合和自動生成 SDK 的優勢。此功能旨在彌補 Data Connect 宣告式語法與複雜 SQL 操作之間的落差,特別是在視窗函數、地理空間索引和複雜的原子操作等進階場景中。

原生 SQL 的運作原理

原生 SQL 透過在 Data Connect 的查詢和變動型別上新增根欄位實現。開發者在標準 .gql 操作檔案中定義具名操作,傳入原始 SQL 字串和參數列表。執行 firebase deploy --only dataconnect 時,Data Connect CLI 會編譯這些操作、驗證 SQL 字串為靜態常數,並拒絕資料定義語言(DDL)等被禁用指令。在執行期,用戶端呼叫具名操作,Data Connect 伺服器安全地將參數綁定到預先部署的 SQL 範本並執行查詢。

查詢和變動型別的操作

查詢字段僅限資料查詢語言(DQL)使用,部署時驗證會阻止 DML 語句:

  • _select:執行預期零個或多個列的查詢,返回 [Any](JSON 陣列)
  • _selectFirst:執行預期恰好一列的查詢,返回 Any(JSON 物件或 null)

變動字段用於資料操作語言(DML),如 INSERT、UPDATE 和 DELETE:

  • _execute:執行 DML 語句,以 Int 形式返回受影響的列數
  • _executeReturning:執行包含 RETURNING 子句的 DML 語句,返回 [Any]
  • _executeReturningFirst:執行 DML 語句,返回單一列

安全性機制

原生 SQL 透過多層防護防止 SQL 注入和未授權存取:

  • 伺服器控制的 SQL:SQL 語句在已部署的 .gql 檔案中硬編碼,用戶端無法在執行期發送任意 SQL
  • 部署時驗證:Data Connect 在部署期間驗證 SQL 字串並拒絕破壞性指令
  • 嚴格參數化:輸入透過 params 陣列傳遞,由資料庫驅動程式綁定到位置預留位置($1、$2),SQL 字串永不與未驗證的輸入連接
  • 伺服器端環境注入:透過 _expr 指令注入受信任的伺服器狀態(如 {_expr: "auth.uid"}),在執行前於伺服器端解析,防止用戶端冒充

原生 SQL 之前無法實現的功能

  • 直接 DML:執行 INSERT、UPDATE 和 DELETE 操作而不依賴 FDC 生成的變動
  • 通用資料表運算式(CTE)的多步驟執行:使用 WITH 關鍵字鏈接多個操作
  • 複雜聚合和視窗函數:執行 RANK()、PARTITION BY 或深層嵌套子查詢
  • 靈活的返回結構:無需在 schema.gql 中撰寫樣板 GraphQL 型別
  • PostgreSQL 擴充:直接查詢 PostGIS 等擴充進行空間資料處理

與 @view 指令的區別

Data Connect 同時提供 @view 指令用於需要嚴格型別安全的讀取場景。@view 將 GraphQL 物件型別與自訂 SELECT 語句關聯,允許在伺服器端封裝複雜資料庫邏輯,同時保持用戶端程式碼的型別安全。然而 @view 為唯讀、無主鍵、所有欄位應宣告為可空,且執行時才驗證 SQL。

選擇合適的 FDC 方案

標準 GraphQL 查詢適合基本 CRUD、簡單連接和強調端到端 (End to End) 型別安全的場景;@view 適合穩定的讀取 SQL 查詢並需要嚴格型別物件的情況;原生 SQL 適合複雜聚合、視窗函數、PostgreSQL 特殊運算子或 CTE 多步驟操作。對於變動,標準 GraphQL 適合常規插入和更新,@transaction 適合跨多個表的原子操作,原生 SQL 適合複雜條件更新、大量資料操作或特定 SQL 邏輯。

最佳實踐與權衡

原生 SQL 的主要代價是失去編譯時型別安全——返回 Any 型別(JSON)意味著用戶端 SDK 無法推斷強型別介面。開發者必須在用戶端程式碼中實施自訂驗證邏輯,安全地將原始 JSON 轉換為預期型別。此外,效能完全取決於查詢規劃器的效率;建議使用 Cloud SQL 主控臺的「查詢洞察」(EXPLAIN ANALYZE)確保不會引入全表掃描。作者特別警告:不要因為不喜歡 GraphQL 就自動用原生 SQL 替換標準操作,會失去自動關聯解析和嚴格用戶端型別的開箱優勢。