文档数据库

SQLite 与 node:sqlite

在 Deno 中使用 node:sqlite 与兼容库,覆盖选型、最小权限与 WAL/备份边界

Deno 自 v2.2 起在 Node 兼容层中提供 node:sqlite,官方 Node API 文档将其列为完整支持模块。上游 Node.js 中该模块加入于 v22.5.0,截至 2026-08-03 上游稳定性标注为 1.2(release candidate),正式稳定前仍可能有小幅 API 调整,升级 Deno 时应复查。

import { DatabaseSync } from "node:sqlite";

const db = new DatabaseSync("./data/app.db");

db.exec(`
  PRAGMA journal_mode = WAL;
  PRAGMA busy_timeout = 5000;
  PRAGMA foreign_keys = ON;

  CREATE TABLE IF NOT EXISTS posts (
    id INTEGER PRIMARY KEY,
    title TEXT NOT NULL
  ) STRICT;
`);

const insert = db.prepare("INSERT INTO posts (title) VALUES (?)");
insert.run("Hello Deno");

const rows = db.prepare("SELECT id, title FROM posts").all();

DatabaseSync 的 API 全部同步执行,适合脚本、CLI 和单写者服务;不要把同步长查询放进高并发请求路径。

备选库

形态注意
node:sqlite内置 Node 兼容模块无需安装依赖;上游仍是 release candidate
jsr:@db/sqliteFFI 加载预编译原生库官方 README 要求 --allow-ffi--allow-env,且需要网络与文件权限下载缓存原生库
npm:better-sqlite3Node 原生 addon依赖 Deno 对原生 addon 的支持,使用前按所用 Deno 版本核对

FFI 与原生 addon 加载机器码,JavaScript 层权限无法约束其系统调用;选型时把这一点计入信任边界。纯 WASM 方案(如 npm:sql.js)不触碰 FFI,但数据库在内存中、持久化要自己处理。

何时选 SQLite

  • 单机服务、CLI 工具、桌面/边缘单实例应用。
  • 测试与本地开发:用 :memory: 或临时文件隔离每个测试。
  • 读多写少的嵌入式场景,配合 WAL 让读写并发。
  • 多区域/边缘副本属于 LiteFS、libsql 一类方案的领域,超出 node:sqlite 范围,选型时单独评估。

最小权限

deno run --allow-read=./data --allow-write=./data src/main.ts
  • WAL 模式会创建 app.db-walapp.db-shm 旁车文件,只授权精确到 app.db 会在 checkpoint 或首次写入时失败;授权目录,或把三个文件全部列出。
  • 只读工具用 new DatabaseSync(path, { readOnly: true }) 配合 --allow-read,不授写权限。
  • jsr:@db/sqlite 等 FFI 方案本质上需要接近 -A 的信任级别,不要用权限收窄自我安慰。

WAL、备份与并发写边界

  • SQLite 是单写者:WAL 下读写可并发,写与写仍互斥;写事务要短,busy_timeout 决定锁竞争时等待多久,超时抛 SQLITE_BUSY
  • 多进程打开同一文件可行,但写吞吐不会因此提高;网络文件系统(NFS 等)上不要使用 SQLite。
  • 备份前先做 PRAGMA wal_checkpoint(TRUNCATE),否则直接拷贝主文件会丢失仍在 WAL 中的提交;或使用 SQLite 官方 CLI 的 .backup
  • 上游 node:sqlite 自 Node v23.8.0 / v22.16.0 起提供 sqlite.backup(),Deno 各版本的支持情况以所用版本实测为准。
  • migration 与 PostgreSQL 同理:作为发布步骤执行,应用启动时自动改 schema 在多实例下会放大并发风险。

官方参考:Deno Node API 支持列表Node.js node:sqlite 文档jsr:@db/sqliteSQLite WAL 模式

输入关键词搜索全部文档。