深入探討MySQL分詞查詢與全文索引技術(shù)
1. 前言
相信小伙伴們在學(xué)習(xí) Spring Cloud
微服務(wù)的過程中涉及到搜索相關(guān)的,你一定會想到使用Elasticsearch
!沒錯 Elasticsearch
很強(qiáng)大,但是對于一些中小型的項(xiàng)目、網(wǎng)站,簡單的一些分詞搜索需求,如果使用 Elasticsearch
無論是硬件成本、開發(fā)開發(fā)成本都大大增加!
如果中小項(xiàng)目中一些簡單的分詞搜索,可以試試 MySQL
分詞查詢,本章節(jié)跟著博主深入探討 MySQL
的分詞查詢技術(shù),從基礎(chǔ)使用到中文處理全面解析。
2. MySQL 全文索引原理
MySQL
自 5.6 起提供了全文索引(Full?Text Index)功能,通過分詞(Tokenization)機(jī)制將一段文本拆分成一個個“詞元”(token),并建立倒排索引,從而實(shí)現(xiàn)高效的分詞查詢
1、分詞(Tokenization
)
將待索引文本(通常是 TEXT 或 VARCHAR)拆分為一個個詞元。例如,英文文本會按空格與標(biāo)點(diǎn)分詞;中文文本默認(rèn)按字符切割,但可配置 ngram 分詞。
2、倒排索引(Inverted Index
)
對每個詞元,記錄它所出現(xiàn)的所有行號(文檔 ID),并統(tǒng)計(jì)詞元出現(xiàn)頻次。查詢時,將搜索詞同樣分詞后,快速在倒排索引中定位相關(guān)文檔。
3、相關(guān)性計(jì)算
MySQL
根據(jù)詞元在文檔中出現(xiàn)的頻次(Term Frequency)、在整個表中出現(xiàn)的文檔數(shù)(Document Frequency)等,使用類似 TF?IDF 的算法計(jì)算相關(guān)度,從高到低排序返回。
3. 配置全文索引與分詞查詢
下面我們以一個articles表,字段 articles_id 、title、content 為例子來進(jìn)行操作,以下是建表語句和測試數(shù)據(jù)
CREATE TABLE `articles` ( `articles_id` int NOT NULL AUTO_INCREMENT COMMENT '文章ID', `title` varchar(255) DEFAULT NULL COMMENT '文章標(biāo)題', `content` text COMMENT '文章內(nèi)容', PRIMARY KEY (`articles_id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; INSERT INTO `articles` (`articles_id`, `title`, `content`) VALUES (1, '分詞MySQL查詢', '跟麥可樂學(xué)編程:MySQL分詞查詢'); INSERT INTO `articles` (`articles_id`, `title`, `content`) VALUES (2, 'MySQL分詞', '跟麥可樂學(xué):MySQL分詞');
3.1 建表與索引
對Mysql熟悉的小伙伴,可以直接使用SQL進(jìn)行設(shè)置
ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title, content) WITH PARSER ngram; -- 中文需指定ngram解析器
喜歡圖形化操作的小伙伴可按下圖設(shè)置
3.2 基本查詢語法
自然語言模式(Natural Language Mode)
SELECT articles_id, title, content, MATCH(title, content) AGAINST('分詞 查詢') AS score FROM articles WHERE MATCH(title, content) AGAINST('分詞 查詢');
默認(rèn)按自然語言解析查詢詞,忽略停用詞、極短詞和頻繁出現(xiàn)詞
查詢輸出效果
布爾模式(Boolean Mode)
SELECT articles_id, title, content FROM articles WHERE MATCH(title,content) AGAINST('+分詞 -查詢' IN BOOLEAN MODE);
查詢輸出效果
3.3 關(guān)鍵操作符
通過布爾模式查詢上圖的效果,下面介紹一下布爾模式支持邏輯運(yùn)算符:
操作符 | 作用 | 示例 |
---|---|---|
+ | 必須包含 | +apple +juice |
- | 必須排除 | apple -macbook |
~ | 相關(guān)性降級 | ~fruit ~vegetable |
* | 通配符 | data* (匹配database等) |
"" | 短語搜索 | "high performance" |
小伙伴們通過上述操作符,就可以自由定制自己的分詞查詢規(guī)則
4. 中文分詞 ngram 與插件方案
4.1 ngram 分詞
MySQL
自帶的 ngram
插件可實(shí)現(xiàn)中文近似分詞:
-- 修改my.cnf(建議token長度2) [mysqld] ngram_token_size=2 -- 建表時指定分詞器 如: CREATE TABLE chinese_news ( id INT PRIMARY KEY, content TEXT, FULLTEXT INDEX (content) WITH PARSER ngram );
配置了 ngram_token_size=2
中文分詞原理,按兩字切分,例如
原始文本:"分詞查詢"
分詞結(jié)果:["分詞","詞查","查詢"]
4.2 第三方分詞插件
Mecab、jieba 插件:將分詞邏輯交給外部庫,實(shí)現(xiàn)更精準(zhǔn)的中文分詞。
這里博主就不做過多介紹了,可以根據(jù)插件文檔進(jìn)行安裝即可
5. 進(jìn)階優(yōu)化與監(jiān)控
1.查詢性能監(jiān)控
- 使用
EXPLAIN
查看FULLTEXT
查詢是否走全文索引。 - 利用慢查詢?nèi)罩竞Y選耗時的全文檢索。
2.分片與分表
對于超大文本表,可按日期或業(yè)務(wù)維度分表分區(qū),保證索引文件大小可控。
3.增量索引
InnoDB 支持后臺算法自動增量更新全文索引,無需手動重建整個索引。
4.權(quán)重調(diào)優(yōu)
MATCH() AGAINST()
可對多列設(shè)置權(quán)重:
MATCH(title) AGAINST('分詞') * 2 + MATCH(content) AGAINST('分詞') AS relevance
6. 結(jié)語
MySQL
分詞查詢?yōu)槿乃阉魈峁┝烁咝У膬?nèi)置解決方案。通過合理配置分詞參數(shù)、選擇合適的分詞器(如 ngram
或第三方插件),并運(yùn)用自然語言模式與布爾模式,小伙伴們可以輕松滿足大多數(shù)中小項(xiàng)目中的搜索場景的需求。對于更復(fù)雜的需求,建議結(jié)合專業(yè)搜索引擎如Elasticsearch
構(gòu)建搜索體系。
到此這篇關(guān)于深入探討MySQL分詞查詢與全文索引技術(shù)的文章就介紹到這了,更多相關(guān)MySQL分詞查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql創(chuàng)建表設(shè)置表主鍵id從1開始自增的解決方案
在MySQL中用很多類型的自增ID,每個自增ID都設(shè)置了初始值,一般情況下初始值都是從0開始,然后按照一定的步長增加(一般是自增 1),下面這篇文章主要給大家介紹了關(guān)于mysql創(chuàng)建表設(shè)置表主鍵id從1開始自增的解決方案,需要的朋友可以參考下2023-04-04MySQL使用UNIQUE實(shí)現(xiàn)數(shù)據(jù)不重復(fù)插入
當(dāng)unique列在一個UNIQUE鍵上插入包含重復(fù)值的記錄時,我們可以控制MySQL如何處理這種情況:使用IGNORE關(guān)鍵字或者ON DUPLICATE KEY UPDATE子句跳過INSERT、中斷操作或者更新舊記錄為新值。2017-05-05Mysql中關(guān)于on,in,as,where的區(qū)別
這篇文章主要介紹了Mysql中關(guān)于on,in,as,where的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03