DeepChat本地存储方案:better-sqlite3与数据持久化实践
2026-02-05 05:52:17作者:曹令琨Iris
方案背景与技术选型
DeepChat作为连接AI与个人数据的智能助手,采用better-sqlite3作为本地存储解决方案,通过src/main/presenter/sqlitePresenter/index.ts实现数据持久化。该方案基于SQLCipher加密扩展,提供事务支持、数据迁移和损坏恢复机制,确保用户对话历史、消息内容等核心数据的安全存储。
技术栈组成
- 核心库:better-sqlite3-multiple-ciphers(SQLCipher扩展版)
- 数据模型:Conversations/Messages/Attachments三表结构
- 安全特性:数据库文件加密、WAL模式、自动备份
- 维护机制:版本迁移、损坏恢复、事务支持
数据库架构设计
核心表结构
DeepChat采用模块化表设计,各表职责明确且通过外键关联:
erDiagram
CONVERSATIONS ||--o{ MESSAGES : contains
MESSAGES ||--o{ MESSAGE_ATTACHMENTS : has
ATTACHMENTS }|--|| MESSAGE_ATTACHMENTS : references
- Conversations表:存储对话元数据(标题、创建时间、设置)
- Messages表:存储消息内容(文本、角色、状态、序号)
- Attachments表:存储文件附件元数据
- MessageAttachments表:消息与附件的多对多关联
初始化流程
数据库连接建立过程包含错误处理与自动恢复机制,关键步骤如下:
// 核心初始化逻辑 [src/main/presenter/sqlitePresenter/index.ts#L32-L92]
constructor(dbPath: string, password?: string) {
this.dbPath = dbPath
try {
// 确保目录存在
const dbDir = path.dirname(dbPath)
if (!fs.existsSync(dbDir)) fs.mkdirSync(dbDir, { recursive: true })
// 初始化加密连接
this.db = new Database(dbPath)
this.db.pragma('journal_mode = WAL')
if (password) {
this.db.pragma(`cipher='sqlcipher'`)
this.db.pragma(`key='${password}'`)
}
// 表初始化与迁移
this.initTables()
this.initVersionTable()
this.migrate()
} catch (error) {
// 损坏恢复流程
this.backupDatabase()
this.cleanupDatabaseFiles()
// 重建数据库
this.db = new Database(dbPath)
// ...重新初始化
}
}
安全存储实现
加密机制
采用SQLCipher实现数据库透明加密,加密密钥通过配置系统安全管理:
// 加密配置 [src/main/presenter/sqlitePresenter/index.ts#L45-L48]
if (password) {
this.db.pragma(`cipher='sqlcipher'`)
this.db.pragma(`key='${password}'`)
}
数据备份策略
数据库损坏时自动创建时间戳备份,并清理损坏文件:
// 备份逻辑 [src/main/presenter/sqlitePresenter/index.ts#L98-L110]
private backupDatabase(): void {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
const backupPath = `${this.dbPath}.${timestamp}.bak`
if (fs.existsSync(this.dbPath)) {
fs.copyFileSync(this.dbPath, backupPath)
console.log(`Database backed up to: ${backupPath}`)
}
}
数据操作接口
核心CRUD实现
SQLitePresenter封装了完整的数据操作API,以下为常用操作示例:
创建对话
// [src/main/presenter/sqlitePresenter/index.ts#L215-L220]
public async createConversation(
title: string,
settings: Partial<CONVERSATION_SETTINGS> = {}
): Promise<string> {
return this.conversationsTable.create(title, settings)
}
插入消息
// [src/main/presenter/sqlitePresenter/index.ts#L254-L278]
public async insertMessage(
conversationId: string,
content: string,
role: string,
parentId: string,
metadata: string = '{}',
orderSeq: number = 0,
tokenCount: number = 0,
status: string = 'pending',
isContextEdge: number = 0,
isVariant: number = 0
): Promise<string> {
return this.messagesTable.insert(/* 参数 */)
}
事务支持
通过better-sqlite3的事务API确保多操作原子性:
// [src/main/presenter/sqlitePresenter/index.ts#L330-L332]
public async runTransaction(operations: () => void): Promise<void> {
await this.db.transaction(operations)()
}
版本迁移与维护
增量迁移机制
系统通过版本表追踪 schema 变更,支持多表协同迁移:
// [src/main/presenter/sqlitePresenter/index.ts#L160-L207]
private migrate() {
const migrations = new Map<number, string[]>()
// 收集各表迁移脚本
tables.forEach((table) => {
for (let version = this.currentVersion + 1; version <= latestVersion; version++) {
const sql = table.getMigrationSQL?.(version)
if (sql) {
migrations.set(version, [...migrations.get(version) || [], sql])
}
}
})
// 按版本顺序执行迁移
const versions = Array.from(migrations.keys()).sort((a, b) => a - b)
for (const version of versions) {
this.db.transaction(() => {
migrationSQLs.forEach(sql => this.db.exec(sql))
this.db.prepare('INSERT INTO schema_versions VALUES (?, ?)')
.run(version, Date.now())
})()
}
}
表版本管理
每个表独立维护版本信息,通过getLatestVersion和getMigrationSQL接口提供迁移脚本:
// 版本管理示例 [src/main/presenter/sqlitePresenter/index.ts#L171-L174]
const latestVersion = tables.reduce((maxVersion, table) => {
const tableMaxVersion = table.getLatestVersion?.() || 0
return Math.max(maxVersion, tableMaxVersion)
}, 0)
性能优化策略
WAL模式
默认启用Write-Ahead Logging模式提升并发性能:
// [src/main/presenter/sqlitePresenter/index.ts#L43]
this.db.pragma('journal_mode = WAL')
WAL模式优势:
- 读操作不阻塞写操作
- 写操作只阻塞其他写操作
- 更小的I/O开销
索引设计
各表通过合理索引优化查询性能,例如Messages表的复合索引:
-- 示例索引设计(推测)
CREATE INDEX idx_messages_conversation_order ON messages(conversation_id, order_seq);
CREATE INDEX idx_messages_parent ON messages(parent_id);
实际应用场景
典型数据流向
以用户发送消息为例,完整数据存储流程:
sequenceDiagram
participant U as User
participant V as ViewModel
participant P as SQLitePresenter
participant M as MessagesTable
U->>V: 发送消息
V->>P: createConversation(标题)
P->>P: 生成conversation_id
V->>P: insertMessage(conversation_id, 内容, "user")
P->>M: insert(消息数据)
M-->>P: 返回message_id
P-->>V: 存储成功
数据恢复案例
当数据库文件损坏时,系统自动执行恢复流程:
1. 创建备份文件(如chat.db.2025-10-23T02-26-17.bak)
2. 删除损坏文件及WAL/SHM文件
3. 重建空数据库并初始化表结构
4. 记录错误日志便于问题排查
扩展与最佳实践
自定义SQL操作
如需执行复杂查询,可通过底层连接直接操作:
// 扩展示例
const customQuery = (conversationId: string) => {
return this.db.prepare(`
SELECT m.* FROM messages m
JOIN conversations c ON m.conversation_id = c.id
WHERE c.id = ? AND m.status = 'completed'
ORDER BY m.order_seq DESC LIMIT 1
`).get(conversationId)
}
备份策略建议
- 定期完整备份(如每日)
- 关键操作前触发增量备份
- 备份文件加密存储
- 定期测试恢复流程
总结
DeepChat的SQLite存储方案通过模块化设计、安全加密和性能优化,为AI助手提供了可靠的数据持久化基础。核心优势包括:
- 安全性:全程加密保护用户隐私数据
- 可靠性:完善的错误处理与自动恢复机制
- 扩展性:版本化迁移支持持续功能迭代
- 性能:WAL模式与索引优化保障操作流畅
完整实现代码参见src/main/presenter/sqlitePresenter/目录,包含表定义、迁移脚本和核心业务逻辑。
登录后查看全文
热门项目推荐
相关项目推荐
GLM-5智谱 AI 正式发布 GLM-5,旨在应对复杂系统工程和长时域智能体任务。Jinja00
GLM-5-w4a8GLM-5-w4a8基于混合专家架构,专为复杂系统工程与长周期智能体任务设计。支持单/多节点部署,适配Atlas 800T A3,采用w4a8量化技术,结合vLLM推理优化,高效平衡性能与精度,助力智能应用开发Jinja00
请把这个活动推给顶尖程序员😎本次活动专为懂行的顶尖程序员量身打造,聚焦AtomGit首发开源模型的实际应用与深度测评,拒绝大众化浅层体验,邀请具备扎实技术功底、开源经验或模型测评能力的顶尖开发者,深度参与模型体验、性能测评,通过发布技术帖子、提交测评报告、上传实践项目成果等形式,挖掘模型核心价值,共建AtomGit开源模型生态,彰显顶尖程序员的技术洞察力与实践能力。00
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00
MiniMax-M2.5MiniMax-M2.5开源模型,经数十万复杂环境强化训练,在代码生成、工具调用、办公自动化等经济价值任务中表现卓越。SWE-Bench Verified得分80.2%,Multi-SWE-Bench达51.3%,BrowseComp获76.3%。推理速度比M2.1快37%,与Claude Opus 4.6相当,每小时仅需0.3-1美元,成本仅为同类模型1/10-1/20,为智能应用开发提供高效经济选择。【此简介由AI生成】Python00
Qwen3.5Qwen3.5 昇腾 vLLM 部署教程。Qwen3.5 是 Qwen 系列最新的旗舰多模态模型,采用 MoE(混合专家)架构,在保持强大模型能力的同时显著降低了推理成本。00- RRing-2.5-1TRing-2.5-1T:全球首个基于混合线性注意力架构的开源万亿参数思考模型。Python00
项目优选
收起
deepin linux kernel
C
27
11
OpenHarmony documentation | OpenHarmony开发者文档
Dockerfile
567
3.83 K
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Java
68
20
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
12
1
暂无简介
Dart
798
197
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
1.37 K
779
喝着茶写代码!最易用的自托管一站式代码托管平台,包含Git托管,代码审查,团队协作,软件包和CI/CD。
Go
23
0
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
349
200
Ascend Extension for PyTorch
Python
376
446
无需学习 Kubernetes 的容器平台,在 Kubernetes 上构建、部署、组装和管理应用,无需 K8s 专业知识,全流程图形化管理
Go
16
1