mysql|參考|參考手冊|全文檢索搜尋|中文 MySQL 4.1.0 中文參考手冊 --- 犬犬(心帆)翻譯 MySQL Reference Manual for version 4.1.0-alpha.
6.8 MySQL 全文檢索搜尋
到 3.23.23 時,MySQL 開始支援全文索引和搜尋。全文索引在 MySQL 中是一個 FULLTEXT 類型索引。FULLTEXT 索引用於 MyISAM 表,可以在 CREATE TABLE 時或之後使用 ALTER TABLE 或 CREATE INDEX 在 CHAR、VARCHAR 或 TEXT 列上建立。對於大的資料庫,將資料裝載到一個沒有 FULLTEXT 索引的表中,然後再使用 ALTER TABLE (或 CREATE INDEX) 建立索引,這將是非常快的。將資料裝載到一個已經有 FULLTEXT 索引的表中,將是非常慢的。
全文檢索搜尋通過 MATCH() 函數完成。
mysql> CREATE TABLE articles ( -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -> title VARCHAR(200), -> body TEXT, -> FULLTEXT (title,body) -> );Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO articles VALUES -> (NULL,'MySQL Tutorial', 'DBMS stands for DataBase ...'), -> (NULL,'How To Use MySQL Efficiently', 'After you went through a ...'), -> (NULL,'Optimising MySQL','In this tutorial we will show ...'), -> (NULL,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), -> (NULL,'MySQL vs. YourSQL', 'In the following database comparison ...'), -> (NULL,'MySQL Security', 'When configured properly, MySQL ...');Query OK, 6 rows affected (0.00 sec)Records: 6 Duplicates: 0 Warnings: 0mysql> SELECT * FROM articles -> WHERE MATCH (title,body) AGAINST ('database');+----+-------------------+------------------------------------------+| id | title | body |+----+-------------------+------------------------------------------+| 5 | MySQL vs. YourSQL | In the following database comparison ... || 1 | MySQL Tutorial | DBMS stands for DataBase ... |+----+-------------------+------------------------------------------+2 rows in set (0.00 sec)
當 MATCH() 被使用在一個 WHERE 子句中時 (參看上面的例子),返回的記錄行被自動地以相關性從高到底的次序排序。相關性值是非負的浮點數字。零相關性意味著不相似。相關性的計算是基於:詞在記錄行中的數目、在行中唯一詞的數目、在集中詞的全部數目和包含一個特殊詞的文檔(記錄行)的數目。
它也可以執行一個邏輯模式的搜尋。這在下面的章節中被描述。
前面的例子是函數 MATCH() 使用上的一些基本說明。記錄行以相似性遞減的順序返回。
下一個樣本顯示如何檢索一個明確的相似性值。如果即沒有 WHERE 也沒有 ORDER BY 子句,返回行是不排序的。
mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles;+----+-----------------------------------------+| id | MATCH (title,body) AGAINST ('Tutorial') |+----+-----------------------------------------+| 1 | 0.64840710366884 || 2 | 0 || 3 | 0.66266459031789 || 4 | 0 || 5 | 0 || 6 | 0 |+----+-----------------------------------------+6 rows in set (0.00 sec)
下面的樣本更複雜一點。查詢返回相似性並依然以相似性遞減的次序返回記錄行。為了完成這個結果,你應該指定 MATCH() 兩次。這不會引起附加的開銷,因為 MySQL 最佳化器會注意到兩次同樣的 MATCH() 調用,並只調用一次全文檢索搜尋代碼。
mysql> SELECT id, body, MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root') AS score -> FROM articles WHERE MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root');+----+-------------------------------------+-----------------+| id | body | score |+----+-------------------------------------+-----------------+| 4 | 1. Never run mysqld as root. 2. ... | 1.5055546709332 || 6 | When configured properly, MySQL ... | 1.31140957288 |+----+-------------------------------------+-----------------+2 rows in set (0.00 sec)
MySQL 使用一個非常簡單的剖析器來將文本分隔成詞。一個“詞”是由文字、資料、“'” 和 “_” 組成的任何字元序列。任何在 stopword 列表上出現的,或太短的(3 個字元或更少的)的 “word” 將被忽略。
到 4.0.1 時,MySQL 也可以使用 IN BOOLEAN MODE 修飾語來執行一個邏輯全文檢索搜尋。
mysql> SELECT * FROM articles WHERE MATCH (title,body) -> AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);+----+------------------------------+-------------------------------------+| id | title | body |+----+------------------------------+-------------------------------------+| 1 | MySQL Tutorial | DBMS stands for DataBase ... || 2 | How To Use MySQL Efficiently | After you went through a ... || 3 | Optimising MySQL | In this tutorial we will show ... || 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... || 6 | MySQL Security | When configured properly, MySQL ... |+----+------------------------------+-------------------------------------+
這個查詢返回所有包含詞 MySQL 的記錄行(注意: 50% 的閾值沒有使用),但是它沒有包含詞 YourSQL。注意,一個邏輯模式的搜尋不會自動地以相似值的降序排序記錄行。你可以從上面的結果出看得出來,最高的相似值(包含 MySQL 兩次的那個) 最列在最後,而不是第一位。一個邏輯全文檢索搜尋即使在沒有一個 FULLTEXT 索引的情況下也可以工作,然而它 慢 些。
邏輯全文檢索搜尋支援下面的操作符:
+一個領頭的加號表示,該詞必須出現在每個返回的記錄行中。
-一個領頭的減號表示,該詞必須不出現在每個返回的記錄行中。
預設的 (當既沒有加號也沒有負號被指定時)詞是隨意的,但是包含它的記錄行將被排列地更高一點。這個模仿沒有 IN BOOLEAN MODE 修飾詞的 MATCH() ... AGAINST() 的行為。
MATCH() 列列表必須確切地匹配表的某一 FULLTEXT 索引中定義的列列表,除非 MATCH() 是 IN BOOLEAN MODE 的。
AGAINST() 的參數必須是一個常量字串。6.8.2 微調 MySQL 全文檢索搜尋
不幸地,全文檢索搜尋仍然只有很少的使用者可調參數,雖然增加一些在 TODO 上排列很高。如果你有一個 MySQL 源碼發行(查看章節 2.3 安裝一個 MySQL 源碼發行),你可以發揮對全文檢索搜尋的更多控制。
注意,全文檢索搜尋為最佳的搜尋效果,被仔細地調整了。修改預設值的行為,在大多數情況下,只會使搜尋結果更糟。不要修改 MySQL 的原始碼,除非你知道你在做什麼!
被索引的詞的最小長度由 MySQL 變數 ft_min_word_len 指定。查看章節 4.5.6.4 SHOW VARIABLES。將它改為你所希望的值,並重建你的 FULLTEXT 索引。(這個變數只從 MySQL 4.0 開始被支援)
stopword 列表可以從 ft_stopword_file 變數指定的檔案中讀取。查看章節 4.5.6.4 SHOW VARIABLES。在修改了 stopword 列表後,重建你的 FULLTEXT 索引。(這個變數只從 MySQL 4.0.10 開始被支援)