1. 程式人生 > 實用技巧 >luogu P2519 [HAOI2011]problem a

luogu P2519 [HAOI2011]problem a

前言

在MySQL 5.6版本以前,只有MyISAM儲存引擎支援全文引擎.在5.6版本中,InnoDB加入了對全文索引的支援,但是不支援中文全文索引.在5.7.6版本,MySQL內建了ngram全文解析器,用來支援亞洲語種的分詞.

在學習之前,請確認自己的MySQL版本大於5.7.6.我的版本為5.7.20.同時文中的所有操作都基於InnoDB儲存引擎.

什麼是全文索引?

如果有搞過lucene,solr,es之類的,理解起來會方便許多.

日常我們使用MySQL查詢時,大部分的查詢都是定值或者範圍查詢.類似於下面這樣:

select *
from table 
where id = 1

select
* from table where id > 20

但是當在MySQL中儲存了文字,比如某個欄位的值為堅決貫徹黨的十八大精神,我們想用貫徹和十八大作為關鍵字時都可以搜尋到這條記錄.那麼只能使用like關鍵字.而對於like我們知道,當不是用左邊字首搜尋的時候,無法命中索引,因此對於這條語句select * from articles where content like '%貫徹%',MySQL只能進行全表掃描,逐一進行匹配.這樣的效率極其低下.

而全文索引呢,通過建立倒排索引,可以極大的提升檢索效率.

倒排索引(英語:Inverted index),也常被稱為反向索引、置入檔案或反向檔案,是一種索引方法,被用來儲存在全文搜尋下某個單詞在一個文件或者一組文件中的儲存位置的對映。它是文件檢索系統中最常用的資料結構。

對於倒排索引,這裡不再展開,有興趣的朋友可以自行了解一下.

目前,MySQL僅可以在char,varchar,text屬性的列上建立全文索引.

如何建立全文索引?

建立全文索引的時機與建立其他型別的索引沒什麼不同,可以在建表時候建立,也可以通過alter語句建立.這裡貼一下建表的同時建立全文索引.

CREATE TABLE articles (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    title VARCHAR (200),
    body TEXT,
    FULLTEXT (title, body) WITH
PARSER ngram ) ENGINE = INNODB DEFAULT CHARSET=utf8mb4 COMMENT='文章表';

上述語句建立了一個article表,且對其中的title和body欄位建立了全文索引.

使用alter語句建立索引示例如下:

ALTER TABLE articles ADD FULLTEXT INDEX title_body_index (title,body) WITH PARSER ngram;

如何使用全文索引進行搜尋?

MySQL的全文索引查詢有多種模式,我們一般經常使用兩種.

1. 自然語言搜尋

就是普通的包含關鍵詞的搜尋.

2. BOOLEAN MODE

這個模式和lucene中的BooleanQuery很像,可以通過一些操作符,來指定搜尋詞在結果中的包含情況.比如+嘻哈表示必須包含嘻哈,-嘻哈表示必須不包含,預設為誤操作符,代表可以出現可以不出現,但是出現時在查詢結果集中的排名較高一些.也就是該結果和搜尋詞的相關性高一些.

具體包含的所有操作符可以通過MySQL查詢來檢視:

使用自然語言搜尋如下:

可以看到,搜尋結果命中了一條,且在不指定搜尋模式的情況下,預設模式為自然語言搜尋.

使用boolean搜尋如下:

當搜尋必須命中精神時,命中了一條資料,當在加上不能包含貫徹的時候,無命中結果.

總結

InnoDB支援全文索引,當然是個好訊息,在一些小的全文搜尋場景下,可以只使用關係型資料庫就搞定了.

他的效率比起like當然是高了不少,但是我沒有測試過在千萬級資料量下的搜尋效率,因為搞出千萬級的測試資料是在是太麻煩了.不過我想在大資料量的情景下表現應該不是很好.

對於全文索引的需求,如果只是很小的資料量,且對搜尋結果的精確度和可定製化程度要求不高的話,可以使用MySQL的全文索引,如果是專門的做搜尋,對搜尋中的分詞以及結果都有較高的要求,建議還是使用lucene,es相關的哪一套全文搜尋工具包來做.

轉載於:https://www.cnblogs.com/yehuisir/p/11340558.html