
SQLite 在生产环境中被低估
SQLite 每天在所有设备上执行超过 1 万亿次查询。借助现代工具,它完全可以用于生产级 Web 服务。

为什么选择 SQLite 用于生产?
- 无需独立服务器进程 — 部署更简单
- 读取可无限扩展 — 文件可复制
- 写入吞吐量:使用 WAL 模式可达 10 万+ 写入/秒
- 零配置 — 无需连接池
- 比等效的 PostgreSQL 数据小 35%
WAL 模式(必备)
import sqlite3
conn = sqlite3.connect('app.db')
cursor = conn.cursor()
# 启用 WAL 模式(对并发访问至关重要)
cursor.execute('PRAGMA journal_mode=WAL')
# 性能调优
cursor.execute('PRAGMA synchronous=NORMAL') # 更快,WAL 模式下仍然安全
cursor.execute('PRAGMA cache_size=10000') # 10MB 页面缓存
cursor.execute('PRAGMA temp_store=MEMORY')
cursor.execute('PRAGMA mmap_size=268435456') # 256MB 内存映射 I/O
conn.commit()
WAL 允许:
- 多个并发读取器在有写入器时仍可工作
- 一次只有一个写入器(串行化)
- 读取性能不受写入器影响

Better SQLite(Node.js 的 better-sqlite3)
import Database from 'better-sqlite3'
const db = new Database('app.db', { verbose: console.log })
// WAL 模式设置
db.pragma('journal_mode = WAL')
db.pragma('synchronous = NORMAL')
db.pragma('foreign_keys = ON')
// 预编译语句只编译一次,可重复使用
const getUser = db.prepare('SELECT * FROM users WHERE id = ?')
const insertUser = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
const updateUser = db.prepare('UPDATE users SET name = ? WHERE id = ?')
// 同步 API — 无需 async/await!
const user = getUser.get(42)
const result = insertUser.run('Alice', 'alice@example.com')
console.log(result.lastInsertRowid) // 自增 ID
// 事务(原子性,快速 — 包装多个语句)
const transferPoints = db.transaction((fromId: number, toId: number, points: number) => {
db.prepare('UPDATE users SET points = points - ? WHERE id = ?').run(points, fromId)
db.prepare('UPDATE users SET points = points + ? WHERE id = ?').run(points, toId)
})
transferPoints(1, 2, 100) // 原子操作!
Litestream:持续复制
# litestream.yml
dbs:
- path: /app/data/app.db
replicas:
- url: s3://my-bucket/app.db
sync-interval: 1s
- url: gcs://my-bucket/app.db # Google Cloud Storage
# 后台复制到 S3
litestream replicate -config litestream.yml
# 从 S3 恢复(灾难恢复)
litestream restore -config litestream.yml -replica s3 /app/data/app.db
# Docker:与应用程序一起运行
CMD ["litestream", "replicate", "-exec", "node server.js"]

Turso:分布式 SQLite
import { createClient } from '@libsql/client'
const db = createClient({
url: 'libsql://my-db-username.turso.io',
authToken: process.env.TURSO_AUTH_TOKEN,
})
// 相同的 SQLite API,全球分布式
const result = await db.execute('SELECT * FROM users WHERE id = ?', [42])
const users = result.rows
// 批量操作
await db.batch([
{ sql: 'INSERT INTO users (name) VALUES (?)', args: ['Alice'] },
{ sql: 'INSERT INTO users (name) VALUES (?)', args: ['Bob'] },
])
SQLite 与 PostgreSQL 的选择时机
| 场景 | SQLite | PostgreSQL |
|---|---|---|
| 单服务器应用 | ✅ | ✅ |
| 读密集型 API | ✅ 副本容易 | ✅ |
| 写密集型(>1000 写入/秒) | ❌ | ✅ |
| 复杂查询/分析 | ⚠️ 有限 | ✅ |
| 多租户 SaaS | ✅ 每租户一个数据库 | ⚠️ |
| Edge 函数 | ✅ Turso | ❌ 太重 |
| 嵌入式/移动端 | ✅ 原生 | ❌ |
性能基准测试
// 插入 10 万行
const stmt = db.prepare('INSERT INTO events (type, data) VALUES (?, ?)')
const insert100k = db.transaction(() => {
for (let i = 0; i < 100_000; i++) {
stmt.run('click', JSON.stringify({ x: i, y: i }))
}
})
const start = performance.now()
insert100k()
console.log(`100k inserts: ${performance.now() - start}ms`)
// ~200ms — 约 50 万插入/秒!