MySQL索引系列:全文索引(关系型数据库管理系统)
大家好,又見面了,我是你們的朋友風君子。
什么是全文索引?
全文索引首先是 MySQL 的一種索引類型,也是搜索引擎的關鍵技術。
試想在1M大小的文件中搜索一個詞,可能需要幾秒,在100M的文件中可能需要幾十秒,如果在更大的文件中搜索那么就需要更大的系統開銷,這樣的開銷是不現實的。
所以在這樣的矛盾下出現了全文索引技術,有時候有人叫倒排文檔技術。
全文索引的作用是什么?
全文索引是將存儲在數據庫中的大段文本中的任意內容信息查找出來的技術。
既然是查找包含某些內容的文本,用 like + 通配符 或者正則表達式就可以實現模糊匹配,為什么還要全文索引?
- 性能:通配符和正則表達式匹配通常要求MySQL嘗試匹配表中所有行(而且這些搜索極少使用表索引)。因此,由于被搜索行數不斷增加,這些搜索可能非常耗時。
- 明確控制:使用通配符和正則表達式匹配,很難明確地控制匹配什么和不匹配什么。例如,指定一個詞必須匹配,一個詞必須不匹配;而一個詞僅在第一個詞確實匹配的情況下,才可以匹配或者才可以不匹配等。這些情況,使用通配符和正則表達式都不滿足。
- 智能化的結果:雖然基于通配符和正則表達式的搜索提供了非常靈活的搜索方式,但它們都不能提供一種智能化的選擇結果的方法。 例如,一個特殊詞的搜索將會返回包含該詞的所有行,而不區分包含單個匹配的行和包含多個匹配的行(按照可能是更好的匹配來排列它們)。類似,一個特殊詞的搜索將不會找出不包含該詞但 包含其他相關詞的行。
所有這些限制以及更多的限制都可以用全文本搜索來解決。在使用全文本搜索時,MySQL不需要分別查看每個行,不需要分別分析和處理每個詞,可以根據需要獲取全文中有關章,節,段,句,詞等信息,也可以進行各種統計和分析。MySQL創建指定列中各詞的一個索引,搜索可以針對這些詞進行。這樣,MySQL可以快速有效地決定哪些詞匹配(哪些行包含它們), 哪些詞不匹配,它們匹配的頻率,等等。
但是全文索引可能存在精度問題。
假如我們要搜索 胡歌很帥,拿百度來舉個例子:
可以看到我明明搜索的是 ‘胡歌很帥’,但是百度搜索的關鍵字(標紅的就是關鍵字)卻不只是完整的 ‘胡歌很帥’,這一句話被分割為’胡歌’,‘很帥’,‘帥’,‘胡歌很’,’胡歌很帥’等,這就是全文索引里的分詞機制,也是導致精度問題的原因。
版本支持
- MySQL 5.6 以前的版本,只有 MyISAM 存儲引擎支持全文索引,InnoDB存儲引擎并不支持全文索引技術,大多數的用戶轉向MyISAM存儲引擎,雖然可以通過表的拆分,將進行全文索引的數據存儲為MyIsam表,這樣方式解決邏輯業務的需求,但是卻喪失了INNODB存儲引擎的事務性;
- MySQL 5.6 及以后的版本,MyISAM 和 InnoDB 存儲引擎均支持全文索引;
- 只有字段的數據類型為 char、varchar、text 及其系列才可以建全文索引。
索引的創建、修改、刪除
具體操作就不重復了,請看上一篇博客:MySQL索引系列:索引概述
使用全文索引
首先創建表,插入測試數據
create table test (
id int(11) unsigned not null auto_increment,
content text not null,
primary key(id),
fulltext key content_index(content)
) engine=Innodb default charset=utf8;
insert into test (content) values ('a'),('b'),('c');
insert into test (content) values ('aa'),('bb'),('cc');
insert into test (content) values ('aaa'),('bbb'),('ccc');
insert into test (content) values ('aaaa'),('bbbb'),('cccc');
按照全文索引的使用語法執行下面查詢:
select * from test where match(content) against('a');
select * from test where match(content) against('aa');
select * from test where match(content) against('aaa');
# 使用完整的 Match() 說明傳遞給 Match() 的值必須與 FULLTEXT() 定義中的相同。如果指定多個列,則必須列
# 出它們(而且次序正確)。且搜索不區分大小寫。
結果發現只有最后那條SQL有一條記錄,為什么呢?
這個問題有很多原因,其中最常見的就是 最小搜索長度 導致的。另外插一句,使用全文索引時,測試表里至少要有 4 條以上的記錄,否則,會出現意想不到的結果。
MySQL 中的全文索引,有兩個變量,最小搜索長度和最大搜索長度,對于長度小于最小搜索長度和大于最大搜索長度的詞語,都不會被索引。通俗點就是說,想對一個詞語使用全文索引搜索,那么這個詞語的長度必須在以上兩個變量的區間內。
這兩個的默認值可以使用以下命令查看
show variables like '%ft%';
可以看到這兩個變量在 MyISAM 和 InnoDB 兩種存儲引擎下的變量名和默認值
// MyISAM
ft_min_word_len = 4;
ft_max_word_len = 84;
// InnoDB
innodb_ft_min_token_size = 3;
innodb_ft_max_token_size = 84;1234567
可以看到最小搜索長度 MyISAM 引擎下默認是 4,InnoDB 引擎下是 3,也即,MySQL 的全文索引只會對長度大于等于 4 或者 3 的詞語建立索引,而剛剛搜索的只有 rabbit 的長度大于等于 3。
配置最小搜索長度
全文索引的相關參數都無法進行動態修改,必須通過修改 MySQL 的配置文件來完成。修改最小搜索長度的值為 1,首先打開 MySQL 的配置文件 /etc/my.cnf,在 [mysqld] 的下面追加以下內容
[mysqld]
innodb_ft_min_token_size = 1
然后重啟 MySQL 服務器,并修復全文索引。注意,修改完參數以后,一定要修復下索引,不然參數不會生效。
兩種修復方式,可以使用下面的命令修復
repair table productnotes quick;
或者直接刪掉重新建立索引,再次執行上面的查詢,就都可以查出來了。
全文搜索的分類
-
自然語言的全文搜索
-
布爾全文搜索
-
帶查詢擴展的全文搜索
關于這幾個分類,具體描述還是看官方手冊手冊吧
參考文章
官方手冊
MySQL必知必會
全文索引的原理
總結
以上是生活随笔為你收集整理的MySQL索引系列:全文索引(关系型数据库管理系统)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第13讲nbsp;日期和时间nbsp;E
- 下一篇: html设置<input type