文章封面图: 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项目