簡介
1).MySQL中的全文索引是FultLeXT類型的索引。
2).全文索引只能用於InnoDB或MyISAM表,只能為CHAR、VARCHAR、TEXT列創建。
3).在MySQL 5.7.6中,MySQL提供了支持中文、日文和韓文(CJK)的內置全文ngram解析器,以及用於日文的可安裝MeCab全文解析器插件
4).當創建表時,可以在CREATE TABLE語句中給出FULLTEXT索引定義,或者稍后使用ALTER TABLE或CREATE INDEX添加該定義。
5).對於大型數據集,將數據加載到沒有FULLTEXT索引的表中然后創建索引要比將數據加載到具有現有FULLTEXT索引的表中快得多。
全文索引的三種類型
- 自然語言搜索將搜索字符串解釋為自然語言中短語。
- 布爾全文搜索
- 查詢擴展搜索
配置
my.ini配置文件中添加
# MySQL全文索引查詢關鍵詞最小長度限制
[mysqld]
ft_min_word_len = 1
保存后重啟MYSQL,執行SQL語句
數據結構: 倒排索引
例子:
-- 創建索引 CREATE TABLE test( title VARCHAR(40), FULLTEXT(title) ); -- 插入數據 INSERT INTO test VALUES('Some like it hot, Some like it cold'), ('Some like it in the pot'), ('Nine days old'), ('Pease porridge in the pot'), ('Pease porridage hot, pease porridge cold'), ('Nine days old');
然后查看一下information_schema下的INNODB_FT_INDEX_TABLE表.如果不允許訪問
就設置一下:SET GLOBAL innodb_ft_aux_table = 'test/test';
然后再查看一下INNODB_FT_INDEX_TABLE或者INNODB_FT_INDEX_CACHE表
會出現類似的記錄,表明已經建立了映射關系
Innodb采用的是full inverted index的存儲方式。這種方式會占用更多的空間,因為它不僅會存儲單詞和單詞所在文檔的ID,還會存儲單詞所在文檔的ID中具體的位置。可以用一個簡單的表格來解釋
相對的,還有一種存儲方式:inverted file index,只存儲單詞及對應的單詞所在文檔。這種理節省空間,但是查找時,只能根據關鍵字得到相應文檔,現進行查找
分詞
通過上面的例子,我們發現,innodb會把單詞拆分進行存儲,查找時,根據單詞匹配(默認是英文符號)
但是有一些詞,我們可能是不能索引查詢的,比如'to',這稱之為stopword;
-- 默認停止詞 SELECT * FROM information_schema.INNODB_FT_DEFAULT_STOPWORD;
或者word的字符長度不在innodb_ft_min_token_size到innodb_ft_max_token_size。默認是3-84個字符區間
INSERT INTO test VALUES -- 90字符 ('123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'), -- 80字符 ('12345678901234567890123456789012345678901234567890123456789012345678901234567890');
插入一個80,90的字符長度,會現在只有80的字符被分詞了:INNODB_FT_INDEX_CACHE表可查,
同理,也只有80的字符記錄被索引
SELECT * FROM test WHERE MATCH(title) AGAINST('12345678901234567890123456789012345678901234567890123456789012345678901234567890');
當然,也可以定制stopword,可以參考mysql stopwords
相關性
如果一個查詢,匹配到多條記錄,是怎么返回呢?根據相關性
-- 查詢相關性 SELECT title, MATCH(title) AGAINST('like') AS relevance FROM test
發現只有前面2條記錄的相關性>0,推斷查詢結果就是取相關性>0的記錄,其實也正是如此。那相關性是怎么計算呢
(1) word(查詢關鍵字)是否在文檔中出現
(2) word在文檔中出現的次數
(3) word在索引列中的數量
(4) 多少個文檔包含該word
所以Some like it hot, Some like it cold,出現了2次like,相關性高
Some like it in who pot出現了1次,相關性低
而其它記錄沒有相關性
檢索模式
Natural Language
上面的例子我們是用的默認的檢索模式,Natural Language模式!表示查詢帶有指定word的文檔。下面2種方式是等價的
SELECT * FROM test WHERE MATCH(title) AGAINST('what' in NATURAL LANGUAGE MODE); SELECT * FROM test WHERE MATCH(title) AGAINST('what');
Boolean
當使用這種模式時,表示字符串前后的字符有特殊含義。比如要查找有Pease單詞的記錄
SELECT * FROM test WHERE MATCH(title) AGAINST('+Pease' in BOOLEAN MODE);
假設,我們需要查找有Pease,但是沒有hot的記錄呢?用+,-符號,分別表示一定存在,或者一定不存在
SELECT * FROM test WHERE MATCH(title) AGAINST('+Pease -hot' in BOOLEAN MODE);
出處:https://blog.csdn.net/weigeshikebi/article/details/80342726