bigywater.tech
MySQL / InnoDB · 89

Full-Text Index

给真实文本建FULLTEXT索引,对比自然语言模式的相关度打分和布尔模式的精确必须/排除筛选。

2倍关系
同时命中2词与只命中1词的真实相关度比例
+/-精确筛选
布尔模式真实支持必须包含/必须排除

做的事:真实建一张带FULLTEXT索引的表,跑自然语言搜索

代码CREATE TABLE ft_test (id INT PRIMARY KEY AUTO_INCREMENT, body TEXT, FULLTEXT(body)); INSERT INTO ft_test (body) VALUES ('MySQL is a popular open source database'), ('PostgreSQL is also a popular open source database'), ('Redis is an in-memory data store'), ('MySQL replication uses binary logs'); SELECT id, body, MATCH(body) AGAINST('MySQL database') AS relevance FROM ft_test WHERE MATCH(body) AGAINST('MySQL database') ORDER BY relevance DESC;

验证:命中词数真实直接决定了相关度分数

实测 · 本机执行输出
id  body                                          relevance
1   MySQL is a popular open source database        0.1812381148338318   ← 同时命中MySQL和database
2   PostgreSQL is also a popular open source db...  0.0906190574169159   ← 只命中database
4   MySQL replication uses binary logs              0.0906190574169159   ← 只命中MySQL

(Redis那一行真实完全没有出现,两个词都不命中)

只命中一个词的两行,相关度分数真实精确相同(0.0906...),同时命中两个词的那一行,分数真实精确是前者的2倍——这是MySQL默认的相关度算法真实体现出的线性叠加特征,同时也真实自动把完全不命中的行(Redis那条)排除在结果集之外,不需要额外的WHERE过滤逻辑。

验证:布尔模式真实支持精确的必须/排除逻辑

实测 · 本机执行输出
SELECT id, body FROM ft_test WHERE MATCH(body) AGAINST('+MySQL -replication' IN BOOLEAN MODE);
→ 只返回 id=1("MySQL is a popular open source database")
   真实精确排除了同样含MySQL但也含replication的id=4
布尔模式下,+词表示这个词必须出现,-词表示这个词必须不出现——本文这条查询真实精确筛出了"含MySQL但不含replication"的那一行,把id=4(同样含MySQL、但也含replication)真实排除在外。这和自然语言模式(按相关度打分、不支持精确的必须/排除)是两种真实不同的使用场景:自然语言模式适合"哪些结果和这段话最相关"这类模糊搜索,布尔模式适合"必须包含A、必须不包含B"这类精确筛选,两者共用同一个FULLTEXT索引,只是查询语法和真实的匹配逻辑不同。

分步演示:自然语言模式的打分和布尔模式的精确筛选

每一步都是本文上面用真实FULLTEXT查询跑出来的原始结果。

相关度分数真实和命中词数线性相关
这一步新验证的搜索模式

    本文用到的工具

    • 本机 MySQL 26.7.0(InnoDB),4条真实文本的FULLTEXT索引
    • MATCH() AGAINST()自然语言模式 vs IN BOOLEAN MODE
    • 没有验证:本文测试短查询词'Sql'(3字符,恰好等于innodb_ft_min_token_size)时真实匹配到了所有含MySQL/PostgreSQL的行,具体的词法边界规则没有进一步深挖
    京ICP备2026067502号-1京公网安备11010502063487号