1. 程式人生 > 實用技巧 >MySQL使用全文索引(fulltext index)

MySQL使用全文索引(fulltext index)

1.建立全文索引(FullText index)

舊版的MySQL的全文索引只能用在MyISAM表格的char、varchar和text的欄位上。

不過新版的MySQL5.6.24上InnoDB引擎也加入了全文索引,所以具體資訊要隨時關注官網,

1.1. 建立表的同時建立全文索引

CREATE TABLE article (
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT(title, body)


) TYPE=MYISAM;

1.2.通過 alter table 的方式來新增

ALTER TABLE `student` ADDFULLTEXTINDEXft_stu_name (`name`)#ft_stu_name是索引名,可以隨便起

或者:ALTER TABLE `student` ADDFULLTEXTft_stu_name (`name`)

1.3. 直接通過create index的方式

CREATEFULLTEXT INDEXft_email_name ON `student` (`name`)

也可以在建立索引的時候指定索引的長度:

CREATEFULLTEXT INDEXft_email_name ON `student` (`name`(20))

2. 刪除全文索引

2.1. 直接使用 drop index(注意:沒有 drop fulltext index 這種用法)

DROP INDEX full_idx_name ON tommy.girl ;

2.2. 使用 alter table的方式

ALTER TABLE tommy.girl DROP INDEX ft_email_abcd;

3.使用全文索引

跟普通索引稍有不同

使用全文索引的格式: MATCH (columnName) AGAINST ('string')

eg:

SELECT * FROM `student`WHEREMATCH(`name`)AGAINST('聰')

當查詢多列資料時:

建議在此多列資料上建立一個聯合的全文索引,否則使用不了索引的。

SELECT * FROM `student`WHEREMATCH(`name`,`address`)AGAINST('聰 廣東')

3.1. 使用全文索引需要注意的是:(基本單位是詞)

分詞,全文索引以詞為基礎的,MySQL預設的分詞是所有非字母和數字的特殊符號都是分詞符(外國人嘛)

這裡推薦一篇文章:利用mysql的全文索引實現模糊查詢

3.2. MySQL中與全文索引相關的幾個變數:

使用命令:mysql>SHOW VARIABLES LIKE 'ft%'; #ft就是FullText的簡寫

ft_boolean_syntax+ -><()~*:""&| #改變IN BOOLEAN MODE的查詢字元,不用重新啟動MySQL也不用重建索引
ft_min_word_len4 #最短的索引字串,預設值為4,(通常改為1)修改後必須重建索引檔案

重新建立索引命令:repair table tablename quick

ft_max_word_len84 #最長的索引字串,預設值為84,修改後必須重建索引檔案

ft_query_expansion_limit20 #查詢括展時取最相關的幾個值用作二次查詢

ft_stopword_file(built-in) #全文索引的過濾詞檔案,具體可以參考:MySQL全文檢索中不進行全文索引預設過濾詞


特別注意:50%的門坎限制(當查詢結果很多,幾乎所有記錄都有,或者極少的資料,都有可能會返回非所期望的結果)

-->可用IN BOOLEAN MODE即可以避開50%的限制。

此時使用全文索引的格式就變成了:SELECT * FROM `student`WHEREMATCH(`name`)AGAINST('聰'IN BOOLEAN MODE)

更多內容請參考:MySQL中的全文檢索(1)

4. ft_boolean_syntax(+ -><()~*:""&|)使用的例子:

4.1 + : 用在詞的前面,表示一定要包含該詞,並且必須在開始位置。

eg: +Apple 匹配:Apple123, "tommy,Apple"

4.2 - : 不包含該詞,所以不能只用「-yoursql」這樣是查不到任何row的,必須搭配其他語法使用。

eg: MATCH (girl_name) AGAINST ('-林志玲 +張筱雨')

匹配到: 所有不包含林志玲,但包含張筱雨的記錄

4.3. 空(也就是預設情況),表示可選的,包含該詞的順序較高。

例子:

apple banana 找至少包含上面詞中的一個的記錄行

+apple +juice 兩個詞均在被包含

+apple macintosh 包含詞 “apple”,但是如果同時包含 “macintosh”,它的排列將更高一些

+apple -macintosh 包含 “apple” 但不包含 “macintosh”

4.4. > :提高該字的相關性,查詢的結果會排在比較靠前的位置。

4.5.< :降低相關性,查詢的結果會排在比較靠後的位置。

例子:4.5.1.先不使用 ><

select * from tommy.girl where match(girl_name) against('張欣婷' in boolean mode);

可以看到完全匹配的排的比較靠前

4.5.2. 單獨使用 >

select * from tommy.girl where match(girl_name) against('張欣婷>李秀琴' in boolean mode);

使用了>的李秀琴馬上就排到最前面了

4.5.3. 單獨使用 <

select * from tommy.girl where match(girl_name) against('張欣婷<不是人' in boolean mode);

看到沒,不是人也排到最前面了,這裡使用的可是 < 哦,說好的降低相關性呢,往下看吧。

4.5.4.同時使用><

select * from tommy.girl where match(girl_name) against('張欣婷>李秀琴<練習冊<不是人>是個鬼' in boolean mode);

到這裡終於有答案了,只要使用了 ><的都會往前排,而且>的總是排在<的前面

小結一下:1. 只要使用 ><的總比沒用的 靠前;

2. 使用 >的一定比 <的排的靠前(這就符合相關性提高和降低);

3. 使用同一類的,使用的越早,排的越前。

4.6.( ):可以通過括號來使用字條件。

eg: +aaa +(>bbb <ccc) // 找到有aaa和bbb和ccc,aaa和bbb,或者aaa和ccc(因為bbb,ccc前面沒有+,所以表示可有可無),

然後 aaa&bbb>aaa&bbb&ccc>aaa&ccc

4.7. ~ :將其相關性由正轉負,表示擁有該字會降低相關性,但不像「-」將之排除,只是排在較後面。

eg: +apple ~macintosh 先匹配apple,但如果同時包含macintosh,就排名會靠後。

4.8. * :萬用字元,這個只能接在字串後面。

MATCH (girl_name) AGAINST ('+*ABC*') #錯誤,不能放前面

MATCH (girl_name) AGAINST ('+張筱雨*') #正確

4.9. " " :整體匹配,用雙引號將一段句子包起來表示要完全相符,不可拆字。

eg: "tommy huang" 可以匹配 tommy huangxxxxx 但是不能匹配tommyishuang

5.補充:Windows下無法修改 ft_min_word_len的情況,

5. 1. 使用cmd開啟 services.msc,

找到你的 MySQL服務,右鍵Properties,找到你的my.ini所在的路徑

5.2. 停止MySQL,在my.ini中增加 ft_min_word_len = 1,重啟MySQL,

然後使用命令show variables like 'ft_min_word_len';檢視是否生效了