自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL全文檢索中Like索引的實(shí)現(xiàn)

運(yùn)維 數(shù)據(jù)庫運(yùn)維 MySQL
在實(shí)際業(yè)務(wù)中,很難避免MySQL全文檢索并Like索引的這種需求。比如模糊搜索用戶帳號(hào),昵稱之類。本文向您介紹如何在MySQL全文檢索中實(shí)現(xiàn)Like索引。

在數(shù)據(jù)庫使用中,DBA都會(huì)告訴大家SQL的LIKE條件為%XXX%號(hào)時(shí),由于不能使用索引,當(dāng)數(shù)據(jù)量變大時(shí)(比如超過百萬條),全表掃描會(huì)導(dǎo)致性能很差。

但是在實(shí)際業(yè)務(wù)中,很難避免MySQL全文檢索并Like索引的這種需求。比如模糊搜索用戶帳號(hào),昵稱之類。既然這個(gè)需求必須做,但又不可以直接用LIKE。這里我和大家分享一下我們關(guān)于這種需求的一種解決方案。當(dāng)然別人也可能采用過類似的辦法,我不是很清楚。所以也用一下“原創(chuàng)”吧。

MySQL數(shù)據(jù)庫很早就支持全文索引,但是全文索引和LIKE語句是不同的。具體點(diǎn)說,全文索引的單位是詞,耳LIKE匹配的是字符。當(dāng)然實(shí)際的區(qū)別更大,比如“老鼠愛大米”這段文本用全文搜索的話,條件“老鼠愛大米”,“老鼠和大米”,“大米老鼠”,“大米與老鼠”會(huì)搜索到內(nèi)容,但是“愛”,“鼠愛”,“愛大”不會(huì)搜索到內(nèi)容。反之,使用LIKE搜索時(shí),“老鼠和大米”,“大米老鼠”,“大米與老鼠”不會(huì)找到內(nèi)容,而“愛”,“鼠愛”,“愛大”會(huì)找到內(nèi)容。我們這里不討論兩種方式的優(yōu)劣,根據(jù)實(shí)際情況每種功能都會(huì)有各自的實(shí)際需求。比如對于大段文本,全文檢索是最好的方法,但是對于姓名,帳號(hào),昵稱等很短的通常無意義文本,LIKE會(huì)更合適一些。

雖然全文檢索和LIKE搜索不同,但是在特殊情況下,可以用全文搜索功能來實(shí)現(xiàn)LIKE搜索。具體就是每個(gè)字符作為一個(gè)詞,而且使用雙引號(hào)來限制詞精確匹配(簡單點(diǎn)說就是老鼠大米和大米老鼠不同),這樣可以實(shí)現(xiàn)LIKE搜索的功能。

下面還是說一下具體的做法吧。

首先,數(shù)據(jù)庫指定 --ft_min_word_len=2 --ft_stopword_file=""。第一個(gè)參數(shù)是告訴數(shù)據(jù)庫,小于2個(gè)字符的詞忽略。第二個(gè)是告訴數(shù)據(jù)庫不忽略任何特殊詞。這些設(shè)置是給實(shí)現(xiàn)功能創(chuàng)造條件。

然后建搜索表

CREATE TABLE  tbl_search (
  id int(10) unsigned NOT NULL auto_increment,
  name varchar(500),
  PRIMARY KEY  (id),
  FULLTEXT KEY idx_name (name)
) ENGINE=InnoDB AUTO_INCREMENT=1;

 

static String encode(String input) {
if (input == null) return null;
StringBuilder output = new StringBuilder();
for (int i = 0, c = input.length(); i < c; ++i) {
char ch = input.charAt(i);

if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' 
|| ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' 
|| ch == '_' || ch == '-') {
output.append(Integer.toHexString(ch)).append(' ');

} else if (ch >= 'a' && ch <= 'z' || ch >= 'a' && ch <= 'z') {
output.append(Integer.toHexString((int)ch - 32)).append(' ');

} else {
Character.UnicodeBlock block = Character.UnicodeBlock.of(ch);
if (block == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| block == Character.UnicodeBlock.KATAKANA
|| block == Character.UnicodeBlock.HIRAGANA) {
output.append(Integer.toHexString(ch)).append(' ');
} else {
// do nothing
}
}

}

// trim blank
int last = output.length() - 1;
if (last > 0 && output.charAt(last) == ' ') {
output.deleteCharAt(last);
}

return output.toString();
}

使用上面的代碼對要搜索的內(nèi)容編碼,比如內(nèi)容是“藍(lán)皮鼠2008”,編碼后的結(jié)果是“84dd 76ae 9f20 32 30 30 38”。將編碼后的內(nèi)容存入name字段。
 
使用如下SQL語句進(jìn)行搜索

select * from tbl_search where match(name) against('"76ae 9f20 32"' in boolean mode) 

這樣就基本實(shí)現(xiàn)了MySQL全文檢索中的Like索引。

 

【編輯推薦】

  1. MySQL蠶食Oracle市場 六成IT設(shè)施使用開源軟件
  2. 使用調(diào)度和鎖定進(jìn)行MySQL查詢優(yōu)化
  3. MySQL基本調(diào)度策略淺析
  4. MySQL左連接、右連接和內(nèi)連接詳解
責(zé)任編輯:佚名 來源: JavaEye
相關(guān)推薦

2010-11-10 14:18:15

SQL SERVER全

2015-07-13 11:39:25

SphinxSQL

2018-08-22 14:25:42

搜索LuceneQuery

2011-08-30 12:34:18

Oracle C#Oracle Text

2009-03-19 10:24:27

全文檢索文本定位Oracle

2010-05-28 11:14:39

MySQL全文索引限制

2010-06-11 17:00:34

2024-01-25 10:37:33

MySQL數(shù)據(jù)庫ES

2009-07-06 18:18:41

SQL Server全

2010-10-20 10:55:54

SQL Server全

2022-09-07 08:16:09

MySQL索引

2010-07-21 09:58:21

SQL Server全

2012-07-31 10:37:31

Lucene.net

2020-11-20 06:13:04

Like %

2010-07-16 15:42:32

SQL Server

2010-05-04 12:18:43

Oracle Text

2010-07-09 10:36:22

SQL Server

2010-05-27 14:27:30

MySQL全文索引

2010-06-17 10:56:57

SQL Server數(shù)

2011-08-03 10:40:17

SQL Server數(shù)全文檢索
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)