每日一得 MySQL全文檢索筆記

2021-07-11 10:10:11 字數 3872 閱讀 8905

1. mysql 4.x版本及以上版本提供了全文檢索支援,但是表的儲存引擎型別必須為myisam,以下是建表sql,注意其中顯式設定了儲存引擎型別

create

table

articles (

id int unsigned auto_increment not

null

primary

key,

title

varchar(200),

body

text

, fulltext (title,body)

) engine

=myisam default charset=utf8;

其中fulltext(title, body) 給title和body這兩列建立全文索引,之後檢索的時候注意必須同時指定這兩列。

2. 插入測試資料

insert

into articles (title,body) values('

mysql tutorial

','dbms stands for database ...'),

('how to use mysql well

','after you went through a ...'),

('optimizing mysql

','in this tutorial we will show ...'),

('1001 mysql tricks

','1. never run mysqld as root. 2. ...'),

('mysql vs. yoursql

','in the following database comparison ...'),

('mysql security

','when configured properly, mysql ...

');

3. 全文檢索測試

select

*from

articles

where match (title,body) against ('

database

');

檢索結果如下:

5mysql vs. yoursql        in the following database

comparison ...

1mysql tutorial dbms stands for

database ...

說明全文匹配時忽略大小寫。

4. 可能遇到的困擾

到目前為止都很順利,但是如果檢索sql改為下面會怎樣呢?

select

*from

articles

where match (title,body) against ('well

');

結果讓人大跌眼鏡,開始我也困惑了許久,後來去網上查了下才知道原來是這麼回事:

mysql指定了最小字元長度,預設是4,必須要匹配大於4的才會有返回結果,可以用show variables like 'ft_min_word_len' 來檢視指定的字元長度,也可以在mysql配置檔案my.ini 更改最小字元長度,方法是在my.ini 增加一行 比如:ft_min_word_len = 2,改完後重啟mysql即可。
所以上面不能返回結果。但是我用上面的方法改配置檔案並重啟mysql伺服器後,再用show命令檢視,並沒有改變。

另外,mysql還會計算乙個詞的權值,以決定是否出現在結果集中,具體如下:

mysql在集和查詢中的對每個合適的詞都會先計算它們的權重,乙個出現在多個文件中的詞將有較低的權重(可能甚至有乙個零權重),因為在這個特定的集中,它有較低的語義值。否則,如果詞是較少的,它將得到乙個較高的權重,mysql預設的閥值是50%,上面『you』在每個文件都出現,因此是100%,只有低於50%的才會出現在結果集中。
但是如果不考慮權重,那麼該怎麼辦呢?mysql提供了布林全文檢索(boolean fulltext search)

假設well在所有記錄中都出現,並且ft_min_word_len已經改為2,那麼下面的sql檢索語句得到的結果集將包含所有記錄:

select

*from articles where

match (title,body)

against (

'well

'in boolean mode );

5. 布林全文檢索語法

上面通過in boolean mode指定全文檢索模式為布林全文檢索。mysql還提供了一些類似我們平時使用搜尋引擎時用到的的語法:邏輯與、邏輯或、邏輯非等。具體通過幾個sql語句例子來說明

select

*from articles where

match (title,body)

against (''

in boolean mode);

+ 表示and,即必須包含。- 表示not,即不包含。

select

*from articles where

match (title,body)

against (''

in boolean mode);

select

*from articles where

match (title,body)

against (''

in boolean mode);

select

*from articles where

match (title,body)

against (''

in boolean mode);

select

*from articles where

match (title,body)

against (

'in boolean mode);

6. mysql不支援中文的全文檢索

預設mysql不支援中文全文檢索,怎麼辦?大致方法有下面幾個:

a. 擴充套件mysql,新增中文全文檢索支援,難度較大

b. 為中文內容表提供乙個對應的英文索引表(即將fulltext索引列按照一定的規則轉化成英文索引表中的每一條記錄,比如全部進行base64編碼,內容表和英文索引表的id相同),檢索時先將檢索詞也用相同規則轉換成英文,然後再使用。如果還要支援按拼音全文檢索,那麼還需要在索引表中增加對應的拼音內容(就需要中文轉拼音演算法了)。當然如果還需要支援中英文互動搜尋,比如搜尋william時也需要返回威廉,反之亦然,那麼還需要將威廉對應的英文翻譯也存到索引表中去。

參考網上的鏈結,具體做法包括先對中文內容進行分詞,然後中文轉換為四位區位碼存到索引表中。檢索時,包含中文的檢索詞也要先分詞,再轉換為四位區位碼,然後在索引表中進行全文檢索。

7. 核對條目

a. 只有儲存引擎型別為myisam型別的表,並且mysql版本為4.x或者以上才能使用mysql內建的全文檢索支援

b. mysql全文檢索預設不支援中文,且對英文檢索時忽略大小寫

d. mysql全文檢索時,所有fulltext索引列必須使用相同的字符集

e. mysql全文檢索返回結果集時還會考慮權重

f. mysql全文檢索還支援靈活的布林全文檢索模式

每日一得 20150606

mysql error 1217錯誤 error 1217 23000 cannot delete or update a parent row a foreign key constraint fails 可能是mysql在innodb中設定了foreign key關聯,造成無法更新或刪除資料。可...

每日一得 java反射

執行時載入類,使用動態載入,靜態載入出現異常,如下所示 1 使用new方式為靜態載入 public class office if excel equals args 0 結果 編譯異常 2使用反射class方式動態載入 public class officebetter catch excepti...

每日一得 hibernate高階查詢筆記

hibernate高階查詢分三種查詢方式 第一種,標準化物件查詢 主要由四部分組成 criteria critertion order projection 一般查詢條件封裝示例 criteria cri session.createcriteria student.class criterion ...