导读:本期聚焦于弥生美月创作的《SQLite FTS5全文搜索怎么用?从建表到中文分词配置详解》,敬请观看详情。想给应用加上高效的全文检索能力,又不想额外引入Elasticsearch这类重型搜索引擎?SQLite自带的FTS5扩展或许是最轻量的选择。本文从FTS5的基本原理讲起,详细介绍虚拟表的创建方式、MATCH查询语法、rank排序技巧,以及最让人头疼的中文分词问题该怎么解决。你会了解到FTS5内置分词器的特点与局限,学会通过外部content表同步数据、使用自定义分词器或simple分词方案处理中文,还会看到性能优化与建索引的建议,帮助你用最小的成本在本地实现接近专业搜索引擎的关键词检索体验。

SQLite的FTS5(Full-Text Search version 5)是一个功能相当完善的全文搜索扩展,它以虚拟表的形式存在,能够在不引入任何外部依赖的情况下,为应用提供倒排索引能力。对于桌面软件、移动端App、小型网站这类数据量在百万级以内的场景,FTS5的性能完全够用,而且维护成本几乎为零。这篇文章从建表开始,一步步讲清FTS5的用法,并重点讨论中文场景下的分词配置问题。

SQLite FTS5全文搜索怎么用?从建表到中文分词配置详解

FTS5是什么,为什么值得用

FTS5是SQLite 3.9.0之后内置的全文搜索模块,它通过维护一张倒排索引表,把每个分词出现的行号和位置记录下来,使得查询时不必逐行扫描,速度远快于LIKE '%关键词%'这种模糊匹配。LIKE查询无法利用普通索引,数据量一上来就会退化成全表扫描,而FTS5的查询复杂度只与命中行数相关。

FTS5相比它的前代FTS4有几个明显优势:支持更灵活的排名函数bm25(),查询语法更接近主流搜索引擎(支持AND、OR、NOT、NEAR等操作符),索引体积更小,并且可以按列建立索引权重。它的典型应用场景包括聊天记录搜索、笔记软件、邮件归档、日志检索等本地化数据查询。

需要注意的是,FTS5默认随官方发行版一起编译,但某些精简编译版(比如部分Linux发行版的系统自带版本)可能没有启用。可以通过执行SELECT fts5(?);,如果返回错误则说明当前环境不支持,需要重新编译SQLite并打开SQLITE_ENABLE_FTS5选项。

创建FTS5虚拟表与基本查询

FTS5表是一种虚拟表,创建语法很简单。下面是一个最基础的例子:

-- 创建一张带全文索引的虚拟表
CREATE VIRTUAL TABLE notes USING fts5(title, body);

-- 插入数据时会自动分词并建立索引
INSERT INTO notes(title, body) VALUES
  ('SQLite教程', 'SQLite是一个轻量的嵌入式数据库'),
  ('全文搜索入门', 'FTS5提供高效的倒排索引能力');

-- MATCH查询:默认多个词之间是 AND 关系
SELECT * FROM notes WHERE notes MATCH 'SQLite';
SELECT * FROM notes WHERE notes MATCH '搜索 AND 入门';

-- 使用bm25函数按相关度排序,值越小越相关
SELECT title, bm25(notes) FROM notes
WHERE notes MATCH 'SQLite'
ORDER BY bm25(notes);

几个细节值得注意。第一,MATCH查询必须写在WHERE 表名 MATCH '关键词'的形式,不能直接对某一行用=比较。第二,默认所有列都会被索引,如果某些列只需要存储不需要检索,可以用UNINDEXED标记,例如CREATE VIRTUAL TABLE notes USING fts5(title, body, created_at UNINDEXED);,这样能减小索引体积。

查询语法方面,FTS5支持的操作符相当丰富:AND、OR、NOT是基本逻辑;"精确短语"用双引号包裹可以做短语匹配;NEAR(a b, 5)表示两个词在5个词以内相邻出现;col:词可以限定只在某一列中搜索,例如title:SQLite只匹配标题列。另外,rank是一个特殊的隐藏列,等价于bm25相关度,可以直接ORDER BY rank。

中文分词问题的解决方案

FTS5最大的短板在于内置分词器对中文的支持。默认的unicode61分词器按标点和空白切分,对英文效果好,但遇到连续中文会整句当成一个token,导致中文搜索基本不可用。解决思路主要有三种。

第一种是使用trigram分词器(SQLite 3.34.0起内置),它把文本切成三个字符的滑动窗口片段,天然支持中文,并且还能配合LIKE实现子串匹配:

-- 使用trigram分词器建表
CREATE VIRTUAL TABLE articles USING fts5(
  content,
  tokenize = 'trigram'
);

-- 可以直接匹配中文子串
SELECT * FROM articles WHERE articles MATCH '数据库原理';

trigram的缺点是索引膨胀比较明显,而且搜索词少于三个字符时无法命中。第二种方案是在应用层先把中文文本分好词(比如用jieba),再用空格拼接后写入FTS5,查询时同样先分词再拼接成查询串。这种方案索引小、可控性强,但需要维护分词逻辑的一致性,写入端和查询端必须使用同一套分词器,否则会出现搜不到的情况。

第三种是编译自定义分词器,比如集成Simple或基于ICU的分词实现,直接在C层完成分词。这种方案性能最好,但需要自己维护SQLite的编译产物,部署门槛较高。对于大多数应用,如果搜索词长度可以保证,trigram是最省事的选择;如果对索引体积敏感,应用层分词则更均衡。

数据同步与性能优化建议

实际项目中,通常业务数据存在普通表中,FTS5表只作为搜索索引。这时推荐使用外部内容表(external content table)模式,让FTS5不重复存储数据,只维护索引:

-- content选项指向原始表,不重复存数据
CREATE VIRTUAL TABLE notes_fts USING fts5(
  title, body,
  content='notes',        -- 数据来源表
  content_rowid='id'      -- 对应原始表的主键
);

-- 用触发器保持索引同步
CREATE TRIGGER notes_ai AFTER INSERT ON notes BEGIN
  INSERT INTO notes_fts(rowid, title, body)
  VALUES (new.id, new.title, new.body);
END;
CREATE TRIGGER notes_ad AFTER DELETE ON notes BEGIN
  INSERT INTO notes_fts(notes_fts, rowid, title, body)
  VALUES ('delete', old.id, old.title, old.body);
END;
CREATE TRIGGER notes_au AFTER UPDATE ON notes BEGIN
  INSERT INTO notes_fts(notes_fts, rowid, title, body)
  VALUES ('delete', old.id, old.title, old.body);
  INSERT INTO notes_fts(rowid, title, body)
  VALUES (new.id, new.title, new.body);
END;

这种模式能把存储开销压缩到最低,但要特别注意删除和更新必须通过特殊的'delete'命令写入,否则索引会产生脏数据。如果嫌触发器麻烦,也可以定期执行INSERT INTO notes_fts(notes_fts) VALUES('rebuild');全量重建索引,适合数据更新不频繁的离线场景。

性能方面还有几点经验:索引建立有代价,批量写入时可以先删触发器、写完数据后统一rebuild,比逐行维护索引快一个数量级;查询频繁的列可以配合bm25的列权重参数(如bm25(notes, 10.0, 1.0)表示title权重是body的十倍)来优化排序效果;数据库连接记得开启PRAGMA journal_mode=WAL;,读写并发场景下体验会好很多。掌握这些配置后,FTS5足以支撑绝大多数本地搜索需求,是一个性价比极高的技术选型。

SQLite FTS5全文搜索中文分词修改时间:2026-09-10 03:52:34

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0910/53791.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。