8、組合查詢和全文本搜索

1.UNION

若是咱們要執行多個查詢條件,好比檢索price不高於5或者供應商是1001,1002的商品。咱們可使用where...or...語句:mysql

select products.vend_id,prod_id,prod_price  
from products  
where prod_price<=5 
or products.vend_id in (1001,1002);

可是咱們還可使用union將兩個select語句合併起來:sql

mysql> select products.vend_id,prod_id,prod_price  from products  where prod_price<=5
-> union
-> select products.vend_id,prod_id,prod_price  from products  where products.vend_id in (1001,1002);

這兩個檢索語句結果同樣。數據庫

注意:函數

  • UNION 中的每一個查詢必須包含相同的列、表達式或彙集函數。
  • UNION自動取消包含重複的行。 上述例子中,第一條select返回4個結果,第二條返回5個,可是使用union以後返回8個而不是9個。由於其中有一條既是1002廠商生產的,又是價格不高於5的。

若是咱們不想取消這些行,將union改成union all.學習

若要排序,只能在最後一條select後面跟上order by.它做用於所有語句。3d

2.全文本搜索

  • 並不是全部引擎都支持全文本搜索。 兩個最常使用的引擎爲MyISAM和InnoDB,前者支持全文本搜索,然後者不支持。
  • 在索引以後,SELECT可與Match()和Against()一塊兒使用以實際執行搜索。

也能夠稍後指定,不在建立的時候指定。code

注意在導入數據的時候不要指定fulltext,由於更新索引須要花費時間。blog

使用例子:排序

select note_text  from productnotes 
where Match(note_text) Against('rabbit');

就能夠匹配出出現'rabbit'的文本行。使用LIKE照樣能夠:索引

select note_text from productnotes
where note_text like '%rabbit%';

咱們使用全文本搜索的優勢在於:like返回的記錄順序沒有特別的用處(或者說是規律)。而使用全文本搜索,咱們是按匹配詞的等級返回的。

看下面一條檢索語句,咱們把等級用數值表示出來:

select note_text,match(note_text) against('rabbit') as rank from productnotes \G;

如圖所示,rank值爲0的就是不包含匹配詞'rabbit'的記錄。咱們返回順序是優先級從高到底的順序。
等級值:

  • 等級由MySQL根據行中詞的數目、惟一詞的數目、整個索引中詞的總數以及包含該詞的行的數目計算出來。
  • 文本中詞靠前的行的等級值比詞靠後的行的等級值高。

3. 查詢擴展

除了查找出現匹配詞的行以外,咱們可能還須要檢索出與這個詞有關的行,但匹配的詞卻沒有出如今這行中。

如咱們要檢索與'anvils'匹配的行:

mysql> select note_text from productnotes
-> where match(note_text) against('anvils');

這樣咱們只返回一條數據,其中包含'anvils'.

使用擴展查詢時候:

  • 首先,進行一個基本的全文本搜索,找出與搜索條件匹配的全部行。
  • 其次,MySQL檢查這些匹配行並選擇全部有用的詞。
  • 再其次,MySQL再次進行全文本搜索,此次不只使用原來的條件,並且還使用全部有用的詞。
  • 因此MySQL進行查詢擴展的時候進行了兩次的全文搜索。

至因而如何選擇有用的詞,則以後學習。

語法:

mysql> select note_text from productnotes
-> where match(note_text) against('anvils' with query expansion);

此次咱們返回了7條記錄:

緣由如上圖。

4. 布爾文本搜索

布爾文本搜索即便沒有fulltext索引也可使用。

布爾方式能夠提供如下細節:

  • 要匹配的詞。
  • 要排斥的詞(若是某行包含這個詞,則不返回該行,即便它包含其餘指定的詞也是如此)。
  • 排列提示(指定某些詞比其餘詞更重要,更重要的詞等級更高)。
  • 表達式分組。

    select note_text from productnotes
    -> where match(note_text) against('heavy' in boolean mode);
    此條布爾查詢和全文本搜索一致。但咱們要若是須要排斥一個詞呢?

    mysql> select note_text from productnotes
    -> where match(note_text) against('heavy -rope*' in boolean mode);
    此條布爾查詢就能夠返回不以'rope'開頭的含有'heavy'的記錄。

實例:

5.全文本搜索使用說明。

  • 短詞被忽略。 在索引全文本數據時,短詞被忽略且從索引中排除。短詞定義爲那些具備3個或3個如下字符的詞(若是須要,這個數目能夠更改)。
  • 內建詞被忽略。 MySQL帶有一個內建的非用詞(stopword)列表,這些詞在索引全文本數據時老是被忽略。若是須要,能夠覆蓋這個列表。
  • 50%規則。 許多詞出現的頻率很高,搜索它們沒有用處(返回太多的結果)。所以,MySQL規定了一條50%規則,若是一個詞出如今50%以上的行中,則將它做爲一個非用詞忽略。50%規則不用於 IN BOOLEAN MODE。
  • 小於三行不返回。 若是表中的行數少於3行,則全文本搜索不返回結果(由於每一個詞或者不出現,或者至少出如今50%的行中)。
  • 忽略單引號。 忽略詞中的單引號。例如, don't 索引爲 dont 。
  • 須要詞分隔符。 不具備詞分隔符(包括日語和漢語)的語言不能恰當地返回全文本搜索結果。
  • 僅在 MyISAM 數據庫引擎中支持全文本搜索。
相關文章
相關標籤/搜索