SQLite FTS5 比我想象中强大
SQLite FTS5 比我想象中强大。一行 CREATE VIRTUAL TABLE 解决全文搜索,何必上 ES? 之前对 SQLite 的印象还停留在「嵌入式数据库,单文件,几十 MB 数据封顶」。直到给 MyBlog 接入 FTS5 做全文搜索——索引建好,查询写完,整个过程不到 30 分钟。相比之下,ES 需要 JVM、cluster 配置、shard 策略、analyzer pipeline,光是启动集群就够喝一壶。对个人博客这种量级(几千篇文章),ES 是用大炮打蚊子。 更让我意外的是 FTS5 的内置辅助函数——可以直接在 SQL 里高亮匹配片段,不用前端再写高亮逻辑。highlight(email, 2, "<b>", "</b>") 会在第 3 列里把匹配词用 b 标签包起来。snippet(email, 2, "<b>", "</b>", "...", 5) 则会返回包含匹配词的 5 个 token 片段,前后用省略号连起来。bm25() 排序也比想象中准,ORDER BY bm25(vibe_fts) 自动按相关度从高到低返回结果。 中文这边需要小心一点:默认的 unicode61 tokenizer 并不真正做中文分词,它对非 ASCII 字符大致按字符或简单的「连续非 ASCII 算一个 token」规则切,所以「今天天气很好」会被切成「今天天气很好」一个 token,而不是「今天 / 天气 / 很 / 好」。这意味着如果你存了一篇「今天天气很好」的文章,用户搜「天气」是搜不到的。解决办法有三种:换 simple tokenizer(按单字切,需要编译额外模块)、用 jieba 之类的中文分词插件先在应用层切好再写入、或者干脆接受「模糊搜索时不分词、精确搜索时 LIKE」的混合方案。 我选的是第三种——大部分站内搜索本来就是「用户大致记得某个词出现过」的模糊场景,单字切 + bm25 排序够用。真正的精确搜索用 LIKE '%keyword%' 配合索引列。如果数据量大到 LIKE 都慢,那就得认真考虑 jieba 了。 FTS5 还有一个经常被忽略的好处:它支持 INSERT/UPDATE/DELETE 触发器自动同步索引表。我给 vibe_notes 写了 4 个 trigger(AIUD 各一个),任何对 vibe_notes 的修改都会同步到 vibe_fts。从此不用在应用层手动维护「索引和数据一致性」这个永恒的烦恼。 如果数据量不上亿,单机 SQLite + FTS5 真的是被严重低估的方案。 2026 年的视角看,SQLite 还在继续进化:libSQL(Turso 的底层)已经把 SQLite 拓展到「边缘计算 + 嵌入式副本同步」的场景,能在 Cloudflare Workers 里跑、能跨区域复制。这意味着个人博客这种「单文件 SQLite」的范式,未来还能扩展到「全球分布、零运维」的边缘部署。再叠上 FTS5 和 AI 时代的 RAG(向量化 + 全文混合检索),SQLite 在个人开发者场景下的天花板还在被抬高。