5 分钟搞懂全文检索(中文搜索)
InnoDB Full-Text + ngram parser,让 MariaDB 直接支持中文搜索
TL;DR
MariaDB 内置全文检索,支持中文(用 ngram parser),简单场景能替代 Elasticsearch / Meilisearch。
建表
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
body TEXT,
FULLTEXT KEY ft_title_body (title, body) WITH PARSER ngram
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;关键:WITH PARSER ngram——把字符串切成 N-gram,中日韩这种没空格的语言才能搜。
系统变量
-- 看 ngram 切几字(默认 2)
SHOW VARIABLES LIKE 'ngram_token_size';
-- 不想让"的""了"被搜:自定义停用词
SET GLOBAL innodb_ft_enable_stopword = ON;
SET GLOBAL innodb_ft_server_stopword_table = 'mydb/stopwords';查询
INSERT INTO articles (title, body) VALUES
('MariaDB 入门', '本文介绍 MariaDB 的安装与使用'),
('MySQL 历史', '从 1995 到现在'),
('PostgreSQL 对比 MariaDB', '两个开源数据库的差异');
-- 自然语言模式(默认)
SELECT id, title FROM articles
WHERE MATCH(title, body) AGAINST('MariaDB');
-- 布尔模式(支持 + - "短语")
SELECT id, title FROM articles
WHERE MATCH(title, body) AGAINST('+MariaDB -MySQL' IN BOOLEAN MODE);
-- 短语搜索
SELECT * FROM articles
WHERE MATCH(title, body) AGAINST('"开源 数据库"' IN BOOLEAN MODE);相关度排序
MATCH(...) 在 SELECT 列里返回相关度分数:
SELECT id, title,
MATCH(title, body) AGAINST('MariaDB') AS score
FROM articles
WHERE MATCH(title, body) AGAINST('MariaDB')
ORDER BY score DESC LIMIT 10;性能要点
FULLTEXT必须在 InnoDB 表(MariaDB 10.0+)- 建索引时数据量大会很慢——离峰跑,或者先批量灌数据再建索引
- 不要在 OLTP 写多表上滥用——重写操作会更新索引
何时不该用 MariaDB 全文检索
- 需要模糊纠错("mariaDb" → "MariaDB")
- 需要多语言混合复杂分词
- 需要结果高亮、聚合 facet
- 数据量 > 100M 文档
这些场景换 Meilisearch / Typesense / Elasticsearch / OpenSearch。但 < 100 万条的内部站搜索,MariaDB 全文检索完全够。
与向量检索对比
| 维度 | MariaDB FULLTEXT | MariaDB VECTOR |
|---|---|---|
| 适合 | 关键词匹配 | 语义检索 |
| 维度 | 词袋 | 1536 维向量 |
| 索引 | inverted | HNSW |
| 训练 | 不需要 | 要 embedding 模型 |
实战中常两个一起用:先 FULLTEXT 筛 100 条,再 VECTOR 重排。
详见 RAG with VECTOR。