
JavaScript 中的 OLAP:库与实用示例
发布于:
阅读时间: 3 min
主题: 技术
作者: Leandro Valencia
如何在 JavaScript 中做 OLAP 式分析:DuckDB-Wasm、Apache Arrow、Arquero、Perspective、SQL.js 和 TinyBase 的示例与适用场景。
目录
- 全景:完整引擎 vs. 轻量工具
- DuckDB-Wasm:浏览器里的完整 OLAP 引擎
- Apache Arrow (JS) + Arquero:列式格式加上 dplyr 风格的转换
- Perspective:面向实时 dashboard 的透视引擎
- SQL.js:WebAssembly 里的 SQLite,简单但不是列式
- TinyBase:轻量响应式 store,不是 OLAP 引擎
- 快速对照表
- 怎么选
全景:完整引擎 vs. 轻量工具
逐个讲库之前,先做一个有用的区分。在 JavaScript 里,“我需要聚合数据,但又不能打生产库”大致有两类方案:
编译成 WebAssembly 的真正 OLAP 引擎。 跑分析 SQL,带列式存储、向量化和查询优化器,和 ClickHouse 或 BigQuery 是一类东西,但跑在浏览器或 Node 进程里。主力代表是 DuckDB-Wasm。
内存里的转换和聚合工具。 它们不是数据库引擎,而是操作已经加载好的数据结构(数组、Arrow 表、响应式 store)的库,提供 groupBy、sum 或透视一类操作。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.sum、op.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 才变得重要。
相关文章
继续探索您可能感兴趣的相似内容

法务评估AI供应商必看:隐私、DPA与认证清单
给法务与合规团队的实用检查清单:签约前向AI供应商该要求什么——可签署的DPA、数据驻留与留存、训练退出选项、子处理者名单,以及SOC 2、ISO 27001等认证。

Qwen 与 Gemma:如何选择本地 Ollama 模型
这篇实用指南教你在本地用 Ollama 运行语言模型时,如何在 Qwen 与 Gemma 之间做出选择:覆盖编程、普通硬件、多语言任务以及日常一般用途,先实测再决定。

DuckDB、ClickHouse、Druid或Pinot如何选
DuckDB、ClickHouse、Druid 和 Pinot 解决的是不同问题。用决策树和对比表,按你的实际用例选出正确的 OLAP 引擎,而不是跟着跑分走。
合作
我每天在用的工具,社区可以拿到更好的条件。