
ReadAny数据层拆解SQLitemigrations15个查询模块本地知识库如何组织【免费下载链接】ReadAnyAI-powered cross-platform e-book reader with semantic search, RAG chat, local vector store, notes, TTS, and WebDAV sync.项目地址: https://gitcode.com/gh_mirrors/re/ReadAnyReadAny 是一款 AI 驱动的跨平台电子书阅读器它的书架、笔记、AI 对话和同步数据全都存在本地 SQLite 数据库里。这篇文章带你完整拆解 ReadAny 数据层的组织方式从readany.db主库到 13 步 migrations再到 15 个按领域拆分的查询模块看看一个本地知识库到底是怎么被有条理地组织起来的。整体架构一主一备两个 SQLite 数据库ReadAny 的数据层位于 packages/core/src/db/ 目录采用平台无关的设计——所有数据库操作都通过统一的IDatabase抽象接口执行桌面端Tauri和移动端Expo共用同一套查询代码。核心文件是 db-core.ts它管理着两个数据库实例数据库文件用途readany.db主库存放图书、笔记、对话等参与同步的数据readany_local.db本地库存放仅本机使用的数据不参与同步连接配置几条关键的 PRAGMA在 db-core.ts 中每次打开数据库连接都会执行一组 PRAGMA 配置这是 SQLite 本地知识库性能与稳定性的关键journal_mode WAL—— 开启 WAL 日志模式读写可以并行阅读器打开书籍时不会因为后台写入而卡顿synchronous NORMAL—— 在保证数据安全的前提下提升写入速度foreign_keys ON—— 启用外键约束删掉一本书时相关笔记、书签会被级联清理busy_timeout 15000—— 数据库被占用时最多等待 15 秒再报错表结构一次初始化建好 17 张表initDatabase()见 db-core.ts在首次启动时创建全部核心表。这些表大致分为四大类 书架领域books—— 图书主表包含书名、作者、封面、总页数、当前进度progress和current_cfi阅读位置book_groups/tags/book_tags—— 书架分组和标签体系✍️ 标注领域highlights—— 划线高亮notes—— 读书笔记bookmarks—— 书签 AI 对话领域threads—— 对话线程带有memory_summary字段用于滚动记忆摘要messages—— 消息内容含引用来源citations和推理过程reasoningskills—— 用户自定义 AI 技能 向量检索与同步领域chunks/vector_index_provenance—— RAG 语义搜索的文本分块reading_sessions—— 阅读会话用于统计功能sync_tombstones/sync_metadata—— 同步删除墓碑与设备标识migrations13 步版本化演进数据库升级是本地应用最容易出问题的环节。ReadAny 用 migrations.ts 实现了标准的版本化迁移机制每张迁移记录包含version、description和upSQL 语句支持多条schema_migrations表记录已应用的版本runMigrations()按顺序补跑未执行的迁移单条 SQL 失败会被容忍例如列已存在的情况保证升级幂等从版本 2 到 13我们可以读出产品演进的痕迹版本 2 books 增加 format 列支持多格式电子书 版本 4 books 增加 sync_status按需下载 版本 6 创建 reading_sessions 表阅读统计同步 版本 8 books 增加 deleted_at软删除保留历史 版本 9 新增 book_groups书架分组 版本 13 threads 增加 memory_summaryAI 对话记忆完整迁移定义见 migrations.ts。这种加列不改列、加表不删表的策略让用户升级版本时数据零丢失。15 个查询模块按领域切分数据访问层最直观的组织方式是按领域拆文件。index.ts 作为统一出口barrel把 15 个查询模块聚合对外导出模块文件负责领域典型函数book-queries.ts图书 CRUDinsertBook、setBookSyncStatusgroup-queries.ts书架分组getGroups、updateGrouphighlight-queries.ts高亮标注getHighlightStatsnote-queries.ts读书笔记insertNote、updateNotebookmark-queries.ts书签getBookmarksthread-queries.tsAI 对话线程updateThreadMemorymessage-queries.ts对话消息insertMessagesession-queries.ts阅读会话getReadingSessionsByDateRangechunk-queries.tsRAG 文本分块insertChunksskill-queries.tsAI 技能upsertSkill好处很明确每个模块只关心自己的表代码可独立测试db/ 目录下每个查询模块都配有对应的__tests__/*.test.ts新成员也能通过文件名快速定位功能。而 database.ts 则保留了旧的统一导出保证外部模块升级前后都能正常 import。写入保护重试队列与同步协作本地 SQLite 最常见的坑是database is locked。ReadAny 在 write-retry.ts 中做了两层防护串行化队列——runSerializedDbTask把所有写入任务排进同一个 Promise 队列避免并发写冲突智能重试——runWithDbRetry检测到database is locked等可重试错误时自动等待 12 秒先让同步操作结束后按递增延迟重试最多 5 次另外cleanupOrphanedSyncRows见 db-core.ts会在同步后清理孤行——比如删除了图书但残留的笔记、书签、阅读会话保证本地知识库始终干净一致。小结本地知识库的组织方法论ReadAny 数据层的设计其实给所有本地优先应用提供了四个可复用的经验双库分离区分参与同步的数据主库和纯本地数据本地库同步逻辑更简单PRAGMA 调优WAL busy_timeout 是本地 SQLite 流畅体验的基础版本化迁移用schema_migrations表追踪版本升级永不破坏用户数据领域模块化15 个查询文件按业务切分配合统一的 barrel 出口可测、可维护如果你也想为自己的 App 搭建本地数据层直接阅读 packages/core/src/db/ 目录就是一个现成的参考实现。【免费下载链接】ReadAnyAI-powered cross-platform e-book reader with semantic search, RAG chat, local vector store, notes, TTS, and WebDAV sync.项目地址: https://gitcode.com/gh_mirrors/re/ReadAny创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考