首頁  >  文章  >  資料庫  >  MySQL基礎教學10 — 函數之全文搜尋功能

MySQL基礎教學10 — 函數之全文搜尋功能

黄舟
黄舟原創
2017-02-24 11:44:321687瀏覽

語法:

  •  MATCH (col1,col2,...) AGAINST (expr [IN BOOLEAN MODE | WITH QUERY EXPANSION])

。 MySQL中的全文索引類型FULLTEXT的索引。  FULLTEXT 索引只可用於 MyISAM表;他們可以從CHAR、 VARCHAR或TEXT欄位中作為CREATE TABLE語句的一部分建立,或是隨後使用ALTER TABLE 或 CREATE INDEX被加入。對於較大的資料集,將你的資料輸入一個沒有FULLTEXT索引的表中,然後建立索引, 其速度比把資料輸入現有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 (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 ...');Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> 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()函數對於一個字串執行資料庫內的自然語言搜尋。一個資料庫就是1套1個或2個包含在FULLTEXT內的欄位。搜尋字串作為對AGAINST()的參數而被給定。對於表中的每一行, MATCH() 傳回相關值,即, 搜尋字串和 MATCH()表中指定該行文字之間的一個相似性測量列中。

在預設狀態下, 搜尋的執行方式為不區分大小寫方式。然而,你可以透過對編入索引的列使用二進位排序方式執行區分大小寫的全文搜尋。 例如,可以向一個使用latin1字元集的欄位給定latin1_bin 的排序方式,對於全文搜尋區分大小寫。

如上述所舉例子,當MATCH()被用在一個 WHERE 語句中時,相關值是非負浮點數。零相關的意思是沒有相似性。相關性的計算是基於該行中單字的數目, 該行中獨特子的數目,資料庫中單字的總數,以及包含特殊單字的文件(行)數目。

對於自然語言全文搜索,要求MATCH() 函數中命名的列和你的表中一些FULLTEXT索引中包含的列相同。對於前述問訊, 注意,MATCH()函數(題目及全文)中所命名的欄位和文章表的FULLTEXT索引中的欄位相同。若要分別搜尋題目和全文,應該對每個欄位建立FULLTEXT索引。

或也可以執行布林搜尋或使用查詢擴充進行搜尋。

上面的例子基本上顯示瞭如何使用返回行的相關性順序漸弱的MATCH()函數。而下面的例子則展示了怎樣明確地檢索相關值。回傳行的順序是不定的,原因是  SELECT 語句不包含 WHERE或ORDER BY 子句:

mysql> SELECT id, MATCH (title,body) AGAINST ('Tutorial')    
-> FROM articles;
+----+-----------------------------------------+
| id | MATCH (title,body) AGAINST ('Tutorial') |
+----+-----------------------------------------+
|  1 |                        0.65545833110809 |
|  2 |                                       0 |
|  3 |                        0.66266459226608 |
|  4 |                                       0 |
|  5 |                                       0 |
|  6 |                                       0 |
+----+-----------------------------------------+
6 rows in set (0.00 sec)

下面的範例則較為複雜。詢問傳回相關值,同時將行依照相關性漸弱的順序排序。要達到這個結果,你應該兩次指定MATCH(): 一次在 SELECT 清單中而另一次在 WHERE子句中。這不會造成額外的內務操作,原因是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.5219271183014 |
|  6 | When configured properly, MySQL ... | 1.3114095926285 |
+----+-------------------------------------+-----------------+
2 rows in set (0.00 sec)

表中有2行(0.00 秒)

MySQL FULLTEXT 執行將任何單字字元原形 (字母、數字和底線部分)的序列視為一個單字。這個序列或許也包含單引號 ('),但在一行中不會超過一個。 這意味著 aaa'bbb 會被視為一個單字,而 aaa''bbb則被視為2個單字。位於單字前後的單引號會被FULLTEXT分析程式去掉; 'aaa'bbb' 會變成   aaa'bbb。

FULLTEXT分析程式會透過尋找某些分隔符號來確定單字的起始位置和結束位置,例如' ' (間隔符號)、 , (逗號)以及 . (句號)。假如單字沒有被分隔符號分開,(例如在中文裡 ), 則 FULLTEXT 分析程式不能確定一個字的起始位置和結束位置。為了能夠在這樣的語言中向FULLTEXT 索引添加單字或其它編入索引的術語,你必須對它們進行預處理,使其被一些諸如"之類的任意分隔符分隔開。

一些詞在全文搜尋會被忽略:

  • 任何過於短的字都會被忽略。就是一個像“the” 或“some” 這樣過於平常而被認為是不具語義的詞。一個正確的單字根據其在詞庫和詢問中的重要性而被衡量。原因是在這個特別詞庫中其語義價值較低。 。

    这项技术最适合同大型词库一起使用 (事实上, 此时它经过仔细的调整 )。对于很小的表,单词分布并不能充分反映它们的语义价值, 而这个模式有时可能会产生奇特的结果。例如, 虽然单词 “MySQL” 出现在文章表中的每一行,但对这个词的搜索可能得不到任何结果:

    mysql> SELECT * FROM articles

    -> WHERE MATCH (title,body) AGAINST ('MySQL');

    找不到搜索的词(0.00 秒)

    这个搜索的结果为空,原因是单词 “MySQL” 出现在至少全文的50%的行中。 因此, 它被列入停止字。对于大型数据集,使用这个操作最合适不过了----一个自然语言问询不会从一个1GB 的表每隔一行返回一次。对于小型数据集,它的用处可能比较小。

    一个符合表中所有行的内容的一半的单词查找相关文档的可能性较小。事实上, 它更容易找到很多不相关的内容。我们都知道,当我们在因特网上试图使用搜索引擎寻找资料的时候,这种情况发生的频率颇高。可以推论,包含该单词的行因其所在特别数据集 而被赋予较低的语义价值。 一个给定的词有可能在一个数据集中拥有超过其50%的域值,而在另一个数据集却不然。

    当你第一次尝试使用全文搜索以了解其工作过程时,这个50% 的域值提供重要的蕴涵操作:若你创建了一个表,并且只将文章的1、2行插入其中, 而文中的每个单词在所有行中出现的机率至少为  50% 。那么结果是你什么也不会搜索到。一定要插入至少3行,并且多多益善。需要绕过该50% 限制的用户可使用布尔搜索代码。

    1. 布尔全文搜索

    利用IN BOOLEAN MODE修改程序, MySQL 也可以执行布尔全文搜索:

    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 Well | After you went through a ...        |
    |  3 | Optimizing 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”的行,但检索包含单词“YourSQL”的行。

    布尔全文搜索具有以下特点:

    • 它们不使用 50% 域值。.

    • 它们不会按照相关性渐弱的顺序将行进行分类。你可以从上述问询结果中看到这一点:相关性最高的行是一个包含两个“MySQL” 的行,但它被列在最后的位置,而不是开头位置。

    • 即使没有FULLTEXT,它们仍然可以工作,尽管这种方式的搜索执行的速度非常之慢。

    • 最小单词长度全文参数和最大单词长度全文参数均适用。

    • 停止字适用。

    布尔全文搜索的性能支持以下操作符:

    • +

    一个前导的加号表示该单词必须 出现在返回的每一行的开头位置。

    • -

    一个前导的减号表示该单词一定不能出现在任何返回的行中。

    • (无操作符)

    在默认状态下(当没有指定 + 或–的情况下),该单词可有可无,但含有该单词的行等级较高。这和MATCH() ... AGAINST()不使用IN BOOLEAN MODE修改程序时的运作很类似。

    • > fb0fed43b83fb0652d5f29eaa4ee0614 操作符增强其影响,而 c338afddb723986043c602cf4e852541turnover ac6d106f336d63bff55b998f29a484ef 

      REPAIR TABLE tbl_name QUICK;

      #注意,假如你使用  

      myisamchk 來執行一項修改表索引的操作 (諸如修理或分析 ), 則使用最小單字長度和最大單字長度以及停止字的預設全文參數值重建FULLTEXT索引,除非你已另外指定。這會導致問詢失敗。

      发生这个问题的原因是只有服务器认识这些参数。它们的存储位置不在  MyISAM 索引文件中。若你已经修改了最小单词长度或最大单词长度或服务器中的停止字,为避免这个问题,为你对mysqld所使用的myisamchk 指定同样的ft_min_word_len、 ft_max_word_len和ft_stopword_file值。例如,假如你已经将最小单词长度设置为 3, 则你可以这样修改一个带有myisamchk的表:

      shell> myisamchk --recover --ft_min_word_len=3 tbl_name.MYI

      为保证 myisamchk 及服务器对全文参数使用相同的值, 可将每一项都放在供选文件中的 [mysqld]和 [myisamchk] 部分:

      [mysqld]
      ft_min_word_len=3
      [myisamchk]
      ft_min_word_len=3

      使用 REPAIR TABLE、 ANALYZE TABLE、OPTIMIZE TABLE或ALTER TABLE来代替使用 myisamchk 。这些语句通过服务器来执行,服务器知道使用哪个全文参数值更加合适。

       以上就是MySQL基础教程10 —— 函数之全文搜索功能的内容,更多相关内容请关注PHP中文网(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn