介绍 Postgres Lite:纯 JS 嵌入式引擎,适用于 Node.js、Bun 和浏览器
Source: Dev.to
PostgreSQL 可以说是全球最受喜爱的数据库。但在本地优先开发、边缘计算或基于浏览器的应用场景中,我们通常会选择 SQLite。
为什么?因为在浏览器中或作为 Node/Bun 中零依赖的嵌入式进程运行完整的 Postgres 实例一直很困难——需要庞大的 WASM 二进制文件或网络代理。
什么是 Postgres Lite?
Postgres Lite 是一个定制构建的 SQL 引擎,使用纯 TypeScript/JavaScript 实现 PostgreSQL 方言。它旨在成为一个强大的 SQLite 替代品,能够说“Postgres”,让你可以直接在前端或本地环境中使用后端相同的模式、查询和逻辑。
- 零仿真: 无 WASM 开销。
- 零依赖: 仅纯 JS/TS 逻辑。
- 通用: 可在 Bun、Node.js 和现代浏览器(通过 IndexedDB)中运行。
性能背后的工程实现
构建一个从零开始的数据库引擎不仅仅是解析 SQL。Postgres Lite 实现了多项高级技术,以轻松处理 1 M+ 记录:
Slotted Page Layout – 数据采用固定 4 KB 页面并使用槽页架构组织,防止碎片化并实现对可变长度记录(例如
JSONB、TEXT)的高效管理。B‑Tree Indexing & O(log n) Lookups – 主键和唯一约束由持久化 B‑Tree 实现支持,即使数据集增长,点查找仍保持极快。
Write‑Ahead Logging (WAL) & ACID Compliance – 每一次变更都会先记录到持久化的
.wal文件,然后再应用到主存储。崩溃后,引擎会在下次启动时自动回放 WAL。Volcano Execution Model – 基于迭代器的处理模型逐行拉取执行计划中的数据,因此对百万行表执行
SELECT *时只占用固定且极小的内存。LRU Buffer Pool – 先进的最近最少使用(LRU)缓存保持常访问页面热存,最大限度减少对磁盘或 IndexedDB 的物理 I/O。
快速开始
安装
npm install @pglite/core
# or
bun add @pglite/core在 Node.js / Bun 中使用
import { PGLite } from "@pglite/core";
import { NodeFSAdapter } from "@pglite/core/node-fs";
const db = new PGLite("app.db", { adapter: new NodeFSAdapter() });
await db.exec(`
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
metadata JSONB
)
`);
await db.exec(
"INSERT INTO users (name, metadata) VALUES ($1, $2)",
["Alice", { role: "admin" }]
);
const results = await db.query(
"SELECT * FROM users WHERE name = $1",
["Alice"]
);
console.table(results);在浏览器中使用
import { PGLite } from "@pglite/core";
import { BrowserFSAdapter } from "@pglite/core/browser";
const db = new PGLite("browser_storage", { adapter: new BrowserFSAdapter() });
// Everything else is the same!支持的功能
- 复杂连接:
INNER、LEFT、LATERAL和CROSS JOIN。 - 高级查询: 公共表表达式(CTE)(
WITH)、UNION、INTERSECT和子查询。 - 窗口函数: 通过
OVER (PARTITION BY …)使用ROW_NUMBER()、RANK()。 - JSON 功能: 完全支持
JSONB操作符(->、->>、@>、?)。 - Upsert(插入冲突更新):
ON CONFLICT (col) DO UPDATE SET …
性能基准
内部测试显示:
- 点查找(PK): ~0.2 ms – 0.5 ms。
- 顺序扫描: 10 k 行 < 40 ms。
- 内存使用: 在高查询负载下保持恒定,得益于 Volcano 模型。
如果你是数据库爱好者或寻找更好本地数据处理方式的 JS 开发者,请在 GitHub 上查看该项目: