文章封面圖: JavaScript 中的 OLAP:函式庫與實用範例

JavaScript 中的 OLAP:函式庫與實用範例

發佈於:

閱讀時間: 3 min

主題: 技術

作者: Leandro Valencia

#olap javascript#duckdb wasm#瀏覽器分析#apache arrow#分析型資料庫

如何在 JavaScript 中做 OLAP 式分析:DuckDB-Wasm、Apache Arrow、Arquero、Perspective、SQL.js 和 TinyBase 的範例與適用情境。

目錄

全景:完整引擎 vs. 輕量工具

逐個講函式庫之前,先做一個有用的區分。在 JavaScript 裡,「我需要彙總資料,但又不能打生產庫」大致有兩類方案:

編譯成 WebAssembly 的真正 OLAP 引擎。 跑分析 SQL,帶欄式儲存、向量化和查詢最佳化器,和 ClickHouse 或 BigQuery 是一類東西,但跑在瀏覽器或 Node 行程裡。主力代表是 DuckDB-Wasm。

記憶體裡的轉換和彙總工具。 它們不是資料庫引擎,而是操作已經載入好的資料結構(陣列、Arrow 表、反應式 store)的函式庫,提供 groupBysum 或透視一類操作。Arquero、Perspective 和 TinyBase 屬於這一類,各自路數不同。

SQL.js 夾在中間:它是真正的資料庫引擎(SQLite),但是列儲存而不是欄式,所以在純分析負載上擴展能力不如欄式引擎,儘管它常被當作輕量替代。

DuckDB-Wasm:瀏覽器裡的完整 OLAP 引擎

DuckDB-Wasm 是 DuckDB 編譯到 WebAssembly 的版本——DuckDB 就是我們在 OLAP 指南裡說的、適合裝進一台機器的資料集的預設嵌入式分析引擎。它在瀏覽器和 Node 裡都能跑,不需要伺服器,欄式向量化引擎和相容 PostgreSQL 的 SQL 方言與原生版相同。

它是這份清單裡最強的選項,因為它不是在模擬 OLAP:它是真正的查詢最佳化器,能直接讀 Parquet、CSV 和 JSON,甚至支援 HTTP range requests,不必下載整個檔案。

什麼時候用: 當你需要在用戶端直接跑真正的 SQL——彙總、JOIN、視窗——處理中等規模資料集(從幾 MB 到幾百 MB),又不想要後端基礎建設。適合載入一份資料匯出的嵌入式分析 dashboard、用戶端資料探索工具,或者檔案已經在使用者瀏覽器裡、不想再把重查詢打到伺服器的情境。

引擎初始化並連上之後,對 Parquet 檔案的查詢大致是這樣:

const result = await connection.query(`
  SELECT pais, SUM(importe) AS ingresos
  FROM read_parquet('ventas.parquet')
  GROUP BY pais
  ORDER BY ingresos DESC
`);

console.table(result.toArray());

初始化(選對 WebAssembly bundle、拉起 worker、打開連線)步驟不少,而且版本之間會變,所以這裡不展開:請看你安裝的那一版 DuckDB-Wasm 官方文件裡的準確 setup。

Apache Arrow (JS) + Arquero:欄式格式加上 dplyr 風格的轉換

這兩個函式庫經常一起出現,值得分開理解。

Apache Arrow 不是查詢引擎:它是一種記憶體中的欄式資料格式,跨語言標準化(Python、R、Java、C++、JavaScript 等都有實作)。價值在於很多資料工具——包括 DuckDB-Wasm——都能直接讀寫 Arrow,所以在它們之間搬資料不必序列化成 JSON,也不必重建結構:共享同一套記憶體配置。

Arquero 是面向 JavaScript 的資料轉換函式庫,明確受 R 的 dplyr 啟發。它在欄式表上工作——陣列、型別化陣列或 Arrow 欄——並提供可鏈式呼叫的 API,動詞包括過濾、分組、彙總或連接表。

什麼時候用: 當你已經有 Arrow 格式的資料(例如從 Python 流水線匯出,或由 DuckDB-Wasm 回傳),想在 JavaScript 裡直接鏈式做 roll-up 或彙總,而不寫 SQL。適合 JS 資料筆記本、互動式探索工具,或者團隊已經按 dplyr/pandas 的方式思考、更喜歡那種語法而不是 SQL。

對一張已經載入好的表,用 Arquero 做彙總的簡化例子:

import { table } from 'arquero';

const ventas = table({
  pais: ['ES', 'MX', 'ES', 'AR'],
  importe: [42, 17, 88, 12],
});

const resumen = ventas
  .groupby('pais')
  .rollup({ ingresos: (d) => op.sum(d.importe) });

console.log(resumen.objects());

確切的匯入 API、彙總函式名稱(op.sumop.mean 等),以及如何用 fromArrow() 載入 Arrow 表,最好對照 Arquero 官方文件核實,因為會隨版本變化,也取決於你用的是帶 Arrow 的 bundle 還是另行匯入。

Perspective:面向即時 dashboard 的透視引擎

Perspective 是用 C++ 寫成、編譯到 WebAssembly 的彙總和透視引擎,帶 JavaScript 繫結。它誕生於 J.P. Morgan 內部金融 dashboard,如今是 FINOS 基金會旗下的開源專案。

Perspective 和這份清單裡其他選項的最大不同,是它專門為即時變化的資料設計:支援串流更新、類似資料透視表的互動透視(按列和欄分組、套用彙總、排序),並自帶可直接插進頁面的視覺化元件(<perspective-viewer>)。

什麼時候用: 用例是互動式 dashboard,最終使用者自己操作視圖——拖維度、換彙總、做篩選——底層資料還在即時更新,比如交易面板、營運指標監控,或嵌進產品裡的 BI。如果你只是要跑一次查詢、展示一個固定結果,它就是殺雞用牛刀;那種情境更適合 DuckDB-Wasm 或 Arquero。

SQL.js:WebAssembly 裡的 SQLite,簡單但不是欄式

SQL.js 是 SQLite 編譯到 WebAssembly 的版本,可以在瀏覽器裡跑完整的 SQLite 資料庫,不需要後端。它大概是這份清單裡資歷最老的函式庫,如果你已經會基礎 SQL,也最好上手。

這裡必須誠實說清邊界:SQLite 是列導向資料庫,和 Postgres、MySQL 一樣。沒有欄式儲存,沒有向量化,也沒有為掃描並彙總數百萬列而設計的最佳化器。按術語的技術含義,它不是 OLAP 引擎。

即便如此,它仍常被當作用戶端小分析的輕量替代:幾千到幾萬列的資料集,和真正欄式引擎的效能差距感覺不出來,優勢是函式庫本身簡單、成熟。

什麼時候用: 瀏覽器裡探索小型資料集、快速原型,或者你更需要完整 SQL(包括寫入和交易),而不是彙總數百萬列的效能。資料集再往上長,就遷到 DuckDB-Wasm。

TinyBase:輕量反應式 store,不是 OLAP 引擎

TinyBase 是為 JavaScript 應用狀態設計的反應式資料 store,函式庫體積非常小。它不是按分析引擎來設計的:主要用途是狀態同步、本機持久化和反應式(資料一變,UI 自己更新),精神上更接近狀態管理函式庫,而不是分析資料庫。

我把它放進清單,是因為它確實提供簡單的彙總工具——對一張表計數、加總、求平均——在小應用裡能覆蓋那些否則就得上更重引擎的需求。

什麼時候用: 你要的「分析」其實只是對已經活在應用狀態裡的資料做簡單彙總——計數器、合計、即時更新的平均值——又不想為此加一整套 SQL 引擎。任何看起來像多維 dashboard 或即席查詢的東西,我都不會選它。

快速對照表

函式庫 是什麼 真正的 OLAP 引擎 最適合
DuckDB-Wasm 編譯到 WASM 的 DuckDB 是,欄式且向量化 用戶端或 Node 上的完整分析 SQL
Apache Arrow (JS) + Arquero 欄式格式 + dplyr 風格轉換 格式是,查詢引擎不是 不寫 SQL 的 JS 轉換流水線
Perspective WASM 透視引擎(FINOS) 是,面向互動彙總 帶透視的即時 dashboard
SQL.js 編譯到 WASM 的 SQLite 否(列導向) 小型分析、用戶端簡單 SQL
TinyBase 輕量反應式 store 對應用狀態的簡單彙總

怎麼選

如果你需要在體量可觀的 Parquet 或 CSV 上跑真正的 SQL,又沒有後端:DuckDB-Wasm,不用猶豫。

如果你已經在用 Arrow 格式的資料,更想在 JavaScript 裡鏈式轉換而不是寫 SQL:Arquero

如果你在做互動式 dashboard,使用者要透視即時變化的資料:Perspective

如果資料集很小,只要基礎 SQL,不追求欄式效能:SQL.js

如果只需要應用狀態裡一個反應式計數器或合計:TinyBase,多半連按 OLAP 來想都沒必要。

無論哪種,寫生產程式碼之前先核對你安裝的那一版官方文件:初始化 API(尤其是依賴 worker 和 WebAssembly bundle 的 DuckDB-Wasm 與 Perspective)版本之間變得相當勤。

常見問題

JavaScript 裡有沒有不靠 WebAssembly 的原生欄式 OLAP 引擎?

沒有能和 DuckDB 或 ClickHouse 相提並論的。真正的向量化欄式引擎寫在 C++ 或 Rust 裡,編譯成 WebAssembly 才進入 JavaScript(DuckDB-Wasm、Perspective)。純 JavaScript 沒有同等採用度的這類引擎。

DuckDB-Wasm 能用在 Node 後端,而不只是瀏覽器嗎?

能。DuckDB-Wasm 在瀏覽器和 Node 都能跑。不過純後端還有 DuckDB 的原生 Node 繫結,可以避開 WebAssembly 這一層。哪個更合適,取決於你是否需要在用戶端和伺服器之間共享程式碼。

SQL.js 能替代真正的 OLAP 資料庫嗎?

大批量不行。SQL.js 是列導向 SQLite;適合用戶端的小分析,但在數百萬列的資料集上,擴展能力比不上欄式引擎。

Arquero 必須依賴 Apache Arrow 才能工作嗎?

對普通陣列的基本用法不需要。當你要和已經是這種格式的資料互操作(例如來自 DuckDB-Wasm),或要把結果匯出成 Arrow 時,Arrow 才變得重要。

相關文章

繼續探索您可能感興趣的相似內容

合作

我每天在用的工具,社群可以拿到更好的條件。

含推廣連結。你支付的價格不變。查看全部合作
培訓計畫

準備好將您的想法轉化為真實專案了嗎?

Transforma是一個幫助您以清晰的方法創建、執行和擴展專案的培訓計畫。

了解Transforma計畫