Skip to main content

SQLite 与本地存储

SQLite 是世界上部署最广泛的数据库。在全栈开发中,除了后端的集中式数据库(MySQL / PostgreSQL),我们经常会在边缘计算、桌面端、移动端或测试环境中用到 SQLite。

SQLite 的核心概念

与 MySQL、Redis 等“客户端-服务端(C/S)”架构的数据库不同,SQLite 是一个进程内的、无服务器的(Serverless)、零配置的、单文件的关系型数据库引擎

面试题:SQLite 的优势和劣势分别是什么?

优势:

  1. 零配置与便携性:整个数据库就是一个 .sqlite.db 后缀的跨平台普通磁盘文件,无需安装服务、无需守护进程。
  2. 轻量与极速:直接与磁盘文件交互,没有网络协议栈和 Socket 通信的开销,在单机单线程下,读写速度极快。
  3. ACID 事务支持:麻雀虽小五脏俱全,完全支持标准的 SQL 和 ACID 事务。

劣势(为什么不用作大型 Web 后端):

  1. 并发写入瓶颈:SQLite 默认是文件级别的锁。当一个连接在写入时,整个数据库文件会被锁住,其他连接无法写入甚至读取。虽然现代 SQLite 引入了 WAL(Write-Ahead Logging,预写日志)模式,实现了读写并发,但依然不支持高并发的写入。
  2. 无网络访问:它只能被同一台机器上的程序访问,无法像 MySQL 那样支持多台 Web 服务器连接同一个数据库集群。
  3. 动态类型:SQLite 是弱类型的(它的列类型更像是给开发者的“建议”),你可以把字符串插到整型列里,这有时会导致不可预期的 Bug。

现代 Node.js/前端生态中的应用场景

尽管不适合做高并发的 Web 主数据库,但 SQLite 在现代生态中焕发了“第二春”:

  1. 跨端开发(桌面/移动端)
    • Electron 桌面应用中(如本地笔记软件、效率工具),使用 SQLite 存储本地数据。
    • React Native / Flutter 移动端应用中,作为本地离线数据的持久化存储,随后再与云端同步。
  2. 边缘计算(Edge Computing)与 Serverless
    • 比如 Cloudflare D1,它就是一个构建在 SQLite 之上的全球分布式数据库。边缘函数(Edge Workers)直接读取附近的 SQLite 副本,将延迟降到极低。
  3. 自动化测试
    • 在跑 Jest 等单元测试时,可以使用内存模式的 SQLite(:memory:),测试瞬间跑完且相互隔离,不需要去启动一个沉重的 MySQL 容器。

Node.js 实践

在 Node.js 中,最常用的两个 SQLite 驱动是 sqlite3(基于异步 API)和 better-sqlite3(基于同步 API,性能极高)。

推荐使用 better-sqlite3,因为它充分利用了 SQLite 在同一台机器上没有网络延迟的特点,避免了 Node.js 异步回调带来的开销,在本地读写时性能甚至超过基于异步的驱动。

// 1. 安装:npm install better-sqlite3
const Database = require('better-sqlite3');

// 打开数据库文件,如果不存在则自动创建
const db = new Database('app.db', { verbose: console.log });

// 开启 WAL 模式,极大提升并发读写性能
db.pragma('journal_mode = WAL');

// 2. 初始化表
db.exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER
)
`);

// 3. 插入数据 (使用 prepare 和预编译语句防止 SQL 注入)
const insert = db.prepare('INSERT INTO users (name, age) VALUES (?, ?)');
const info = insert.run('Alice', 28);
console.log('插入的数据 ID:', info.lastInsertRowid);

// 4. 查询数据
const stmt = db.prepare('SELECT * FROM users WHERE age > ?');
const users = stmt.all(20); // 同步返回数组,无需 await
console.log(users);

Prisma 与 SQLite

Prisma 同样完美支持 SQLite。在开发初期或者做个人侧边项目(Side Project)时,可以直接在 schema.prisma 中将 provider 改为 sqlite,一键生成数据库文件,省去了本地搭建 Docker 或 MySQL 环境的麻烦。

// schema.prisma
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}