讓MySQL支持中文全文檢索
■ 楊寶昌
--------------------------------------------------------------------------------
因?yàn)橹形脑~間并沒有明顯的區(qū)隔,所以中文的分詞是按照字典、詞庫(kù)的匹配和詞的頻度統(tǒng)計(jì),或是基于句法、語(yǔ)法分析的分詞,而MySQL并不具備此功能,所以MySQL對(duì)中文全文檢索的支持幾乎為零。
目前很多網(wǎng)站和系統(tǒng)都提供了全文搜索功能,用戶可以輸入詞或者語(yǔ)句來(lái)定位匹配的記錄。在后臺(tái),可以使用Select查詢中的Like語(yǔ)句來(lái)執(zhí)行這種查詢,盡管這種方法可行,但對(duì)于全文查找而言,這是一種效率極端低下的方法,尤其在處理大量數(shù)據(jù)的時(shí)候。MySQL針對(duì)這一問(wèn)題提供了一種基于內(nèi)建的全文查找方式的解決方案。開發(fā)者只需要簡(jiǎn)單地標(biāo)記出需要全文查找的字段,然后使用MySQL方法在那些字段運(yùn)行搜索,這不僅僅提高了性能和效率(因?yàn)镸ySQL對(duì)這些字段做了索引來(lái)優(yōu)化搜索),而且實(shí)現(xiàn)了更高質(zhì)量的搜索,因?yàn)镸ySQL使用自然語(yǔ)言來(lái)智能地對(duì)結(jié)果評(píng)級(jí),以去掉不相關(guān)的項(xiàng)目。這就是MySQL的全文檢索功能。
到MySQL3.23.23時(shí),MySQL開始支持全文索引和搜索。全文索引在MySQL中是一個(gè) FullText類型索引。FullText索引用于MyISAM表,可以在Create Table時(shí)或之后使用Alter Table或Create Index在Char、VarChar或TEXT列上創(chuàng)建。對(duì)于大的數(shù)據(jù)庫(kù),將數(shù)據(jù)裝載到一個(gè)沒有FullText索引的表中,然后再使用Alter Table (或Create Index) 創(chuàng)建索引,這將是非常快的。
但是,眾所周知,在英文排版時(shí)詞間是以空格區(qū)分的,所以英文的分詞是基于空格的。但是涉及到中文等東亞文字就沒有這么簡(jiǎn)單了,因?yàn)橹形脑~間并沒有明顯的區(qū)隔,所以中文的分詞則是按照字典、詞庫(kù)的匹配和詞的頻度統(tǒng)計(jì),或是基于句法、語(yǔ)法分析的分詞,而MySQL并不具備此功能,所以MySQL對(duì)中文全文檢索的支持幾乎為零。
需求及設(shè)計(jì)思想
來(lái)自NetCraft統(tǒng)計(jì)的數(shù)據(jù),截至2006年4月份全球網(wǎng)站數(shù)量超過(guò)8065萬(wàn)個(gè),目前,Linux及Apache在網(wǎng)站操作系統(tǒng)及Web服務(wù)器軟件市場(chǎng)的份額為62.7%。再來(lái)看一份來(lái)自中國(guó)互聯(lián)網(wǎng)絡(luò)信息中心(CNNIC)的調(diào)查報(bào)告,截至2006年1月1日,全國(guó)有69.4萬(wàn)個(gè)網(wǎng)站,在線數(shù)據(jù)庫(kù)數(shù)為29萬(wàn)5400個(gè)。由于中國(guó)使用LAMP(Linux、Apache、MySQL、PHP)套件的數(shù)量沒有達(dá)到世界平均份額,所以估計(jì)有15萬(wàn)左右的基于PHP/MySQL構(gòu)架的網(wǎng)站,這不包括5萬(wàn)個(gè)WAP網(wǎng)站、企業(yè)管理系統(tǒng)、教學(xué)應(yīng)用系統(tǒng)等信息管理系統(tǒng)。如果全都算上,在中國(guó)使用MySQL的站點(diǎn)(系統(tǒng))數(shù)量應(yīng)該在15萬(wàn)至18萬(wàn)之間。
MySQL有如此龐大的使用規(guī)模,中文全文檢索在MySQL的實(shí)現(xiàn)將是相當(dāng)迫切,加之筆者在做一個(gè)網(wǎng)站系統(tǒng)的時(shí)候也是由于租用服務(wù)器硬性環(huán)境,不能自由選擇數(shù)據(jù)庫(kù)或者添加組件,所以只能根據(jù)已有的條件進(jìn)行適應(yīng)性改良。一個(gè)偶然的思路使筆者產(chǎn)生了能否將中文和英文建立特定關(guān)聯(lián),然后再進(jìn)行檢索呢?答案是可以的。MySQL不支持中文全文檢索,但是支持英文全文檢索,可以將“中文全文檢索”轉(zhuǎn)變?yōu)椤坝⑽娜臋z索”,然后再變回“中文全文檢索”。那么中文又如何轉(zhuǎn)換成英文呢?思路可以是:中文全文檢索→拼音全文檢索→中文全文檢索。所以轉(zhuǎn)換的思路如圖1所示。
圖1 中文全文檢索思路
用戶輸入中文信息提交的時(shí)候,通過(guò)一個(gè)中文到拼音的轉(zhuǎn)換程序?qū)⑵鋽?shù)據(jù)轉(zhuǎn)換為拼音的格式存入數(shù)據(jù)庫(kù)中,然后用戶檢索時(shí)同樣是輸入中文,也將檢索詞轉(zhuǎn)換為拼音,到數(shù)據(jù)庫(kù)中進(jìn)行匹配,返回結(jié)果。但是這樣做有兩個(gè)缺點(diǎn):第一個(gè)是,檢索是成功了,可是沒有中文原數(shù)據(jù),如何返回有效結(jié)果?第二個(gè)是,中文轉(zhuǎn)換拼音如果中文篇幅過(guò)長(zhǎng),轉(zhuǎn)換時(shí)間過(guò)長(zhǎng)怎么辦?所以催生了第二種解決方法,如圖2所示。
圖2 改進(jìn)后的檢索思路
如圖2所示,用戶輸入中文按照正常方式直接提交至數(shù)據(jù)庫(kù),然后有一個(gè)后臺(tái)轉(zhuǎn)換程序循環(huán)執(zhí)行,將中文轉(zhuǎn)換為拼音存入另外一張全文檢索表中,其他用戶在進(jìn)行全文檢索時(shí)由于詞語(yǔ)長(zhǎng)度有限,所以可以采用即時(shí)轉(zhuǎn)換拼音,然后進(jìn)行數(shù)據(jù)庫(kù)查詢匹配。
MySQL中文全文檢索實(shí)現(xiàn)
1.?dāng)?shù)據(jù)庫(kù)表結(jié)構(gòu)設(shè)計(jì)
此處用到兩張表,以為人員信息建立全文檢索為例,分為:人員信息表(UserInfo)和全文檢索表(IndexSeek),表結(jié)構(gòu)如圖3所示。
圖3 人員信息表和全文檢索表
人員信息表(UserInfo)各列含義為: ID(id),自增序列;姓名(user_name);個(gè)人介紹(user_introduction);全文檢索狀態(tài)(user_state),新添加或者修改后狀態(tài)為0,拼音轉(zhuǎn)換完成狀態(tài)為1。
全文檢索表(IndexSeek) 各列含義為:ID(id),自增序列;關(guān)聯(lián)人員信息ID(user_id),對(duì)應(yīng)UserInfo表中ID;索引項(xiàng)(index_item),該列設(shè)置為FullText全文檢索;索引標(biāo)示(index_mark),標(biāo)示為哪個(gè)列的索引,本文中涉及兩個(gè)索引,分別為姓名(user_name)、介紹(user_introduction)。
兩個(gè)表中的log字段記錄該行修改的時(shí)間和產(chǎn)生的錯(cuò)誤提示。在本文中無(wú)實(shí)際用途。
2.用戶輸入中文資料
用戶自己輸入信息添加至數(shù)據(jù)庫(kù),例如,各項(xiàng)為:“1”、“張三”、“愛好編程,PHP,MySQL”、“0”。
3.后臺(tái)轉(zhuǎn)換拼音過(guò)程
后臺(tái)應(yīng)用程序按照規(guī)則進(jìn)行中文到拼音的轉(zhuǎn)換,筆者在網(wǎng)上下載了內(nèi)碼→拼音轉(zhuǎn)換數(shù)據(jù)包pinyin.dat,該文件的下載網(wǎng)址為:http://scws.tguanlim.com/py/getpy.php。 以下以PHP代碼為例演示中文→拼音轉(zhuǎn)換。
//my_Getpy漢字轉(zhuǎn)換拼音類[5]
class my_Getpy
{
var $_dat = 'pinyin.dat';
var $_fd = false;
function my_Getpy($pdat = '')
{
if ('' != $pdat)
$this->_dat = $pdat;
}
function load($pdat = '')
{
if ('' == $pdat)
$pdat = $this->_dat;
$this->unload();
$this->_fd = @fopen($pdat, 'rb');
if (!$this->_fd)
{
trigger_error("沒有`$pdat`文件", E_USER_WARNING);
return false;
}
return true;
}
function unload()
{
if ($this->_fd)
{
@fclose($this->_fd);
$this->_fd = false;
}
}
function get($zh)
{
/*if (strlen($zh) != 2)
{
trigger_error("`$zh` is not a valid GBK hanzi", E_USER_WARNING);
return false;
}*/
if (!$this->_fd && !$this->load())
return false;
$high = ord($zh[0]) - 0x81;
$low = ord($zh[1]) - 0x40;
// 計(jì)算偏移位置
$nz = ($ord0 - 0x81);
$off = ($high< <
+ $low - ($high * 0x40);
// 判斷 off 值
fseek($this->_fd, $off * 8, SEEK_SET);
$ret = fread($this->_fd,
;
$ret = rtrim($ret, '\0');
return $ret;
}
function _my_Getpy()
{
$this->_unload();
}
}
//截取字符函數(shù)
function csubstr($str,$start,$len)
{
$strlen=strlen($str);
if ($start>=$strlen)
return $str;
$clen=0;
for($i=0;$i< $strlen;$i++,$clen++)
{
if(ord(substr($str,$i,1))>0xa0)
{
if ($clen>=$start)
$tmpstr.=substr($str,$i,2);
$i++;
}
else
{
if ($clen>=$start)
$tmpstr.=substr($str,$i,1);
}
if ($clen>=$start+$len)
break;
}
return $tmpstr;
}
//計(jì)算字符長(zhǎng)度的函數(shù),漢字中文都當(dāng)作是長(zhǎng)度為1
function StrLenW($str)
{
$count = 0;
$len = strlen($str);
for($i=0; $i< $len; $i++,$count++)
if(ord($str[$i])>=128)
$i++;
return $count;
}
//批量中文轉(zhuǎn)換拼音函數(shù),轉(zhuǎn)換后每個(gè)字符中間加上空格,判斷非中文字符如符號(hào),英文,數(shù)字則不作變動(dòng)
function operate_py($str){
$len_max=StrLenW($str);
$len="0";
$start="0";
$py = new my_Getpy;
for($start=0;$start< $len_max;$start++){
$simp=csubstr($str,$start,$len);
if ( ord($simp)>127 ){
$rs = $py->get($simp);
$rs=" ".$rs." ";
}
else{
$rs=$simp;
}
$rs_return.=$rs;
}
$py=null;
return $rs_return;
}
將該程序循環(huán)執(zhí)行,查詢user_state為0的行,取出user_name、user_introduction兩列數(shù)據(jù),分別進(jìn)行拼音轉(zhuǎn)換,然后插入全文檢索表(IndexSeek)表中,添加兩行數(shù)據(jù),其中第一行為:
關(guān)聯(lián)人員信息ID(user_id):1;//對(duì)應(yīng)UserInfo表中ID,此處為1
索引項(xiàng)(index_item):zhang1 san1;
索引標(biāo)示(index_mark): 姓名(user_name)。
第二行為:
關(guān)聯(lián)人員信息ID(user_id):1;//對(duì)應(yīng)UserInfo表中ID,此處為1
索引項(xiàng)(index_item):ai4 hao3 bian1 cheng2 ,PHP,MySQL;
索引標(biāo)示(index_mark):介紹(user_introduction)。
至此,添加中文數(shù)據(jù)轉(zhuǎn)換拼音過(guò)程完畢。修改用戶信息同樣步驟進(jìn)行,只是不再新添加表,刪除數(shù)據(jù)則根據(jù)關(guān)聯(lián)id全部刪除。
4.用戶檢索過(guò)程
由于用戶檢索時(shí)輸入的關(guān)鍵詞數(shù)量有限,則采用頁(yè)面應(yīng)用程序直接轉(zhuǎn)換拼音進(jìn)行匹配。例如用戶輸入檢索詞為:“編程”,提交給服務(wù)器,由服務(wù)器端程序處理轉(zhuǎn)換為“bian1 cheng2”進(jìn)行數(shù)據(jù)表IndexSeek的全文檢索,全文檢索SQL為:
SELECT * FROM IndexSeekWHERE MATCH (index_item) AGAINST (' bian1 cheng2');
得出關(guān)聯(lián)人員ID為1,然后取得用戶資料表中全部信息返回給用戶。由于中文轉(zhuǎn)換拼音過(guò)程同上,在此不再列出代碼。
更多的英文全文檢索技巧請(qǐng)參看MySQL手冊(cè),這里不再一一介紹。上面便是整個(gè)MySQL中文全文檢索實(shí)現(xiàn)過(guò)程。
本文所提供的方法并不能完全解決MySQL的全文檢索問(wèn)題,由于中文字詞存在同音現(xiàn)象,比如:"清華"和"輕劃"檢索結(jié)果相同,這也是不可避免的,但是對(duì)于MySQL的用戶來(lái)說(shuō),該方法是目前不錯(cuò)的一種折衷手段。
(計(jì)算機(jī)世界報(bào) 2006年09月25日 第37期 B28、B29)
■ 楊寶昌
--------------------------------------------------------------------------------
因?yàn)橹形脑~間并沒有明顯的區(qū)隔,所以中文的分詞是按照字典、詞庫(kù)的匹配和詞的頻度統(tǒng)計(jì),或是基于句法、語(yǔ)法分析的分詞,而MySQL并不具備此功能,所以MySQL對(duì)中文全文檢索的支持幾乎為零。
目前很多網(wǎng)站和系統(tǒng)都提供了全文搜索功能,用戶可以輸入詞或者語(yǔ)句來(lái)定位匹配的記錄。在后臺(tái),可以使用Select查詢中的Like語(yǔ)句來(lái)執(zhí)行這種查詢,盡管這種方法可行,但對(duì)于全文查找而言,這是一種效率極端低下的方法,尤其在處理大量數(shù)據(jù)的時(shí)候。MySQL針對(duì)這一問(wèn)題提供了一種基于內(nèi)建的全文查找方式的解決方案。開發(fā)者只需要簡(jiǎn)單地標(biāo)記出需要全文查找的字段,然后使用MySQL方法在那些字段運(yùn)行搜索,這不僅僅提高了性能和效率(因?yàn)镸ySQL對(duì)這些字段做了索引來(lái)優(yōu)化搜索),而且實(shí)現(xiàn)了更高質(zhì)量的搜索,因?yàn)镸ySQL使用自然語(yǔ)言來(lái)智能地對(duì)結(jié)果評(píng)級(jí),以去掉不相關(guān)的項(xiàng)目。這就是MySQL的全文檢索功能。
到MySQL3.23.23時(shí),MySQL開始支持全文索引和搜索。全文索引在MySQL中是一個(gè) FullText類型索引。FullText索引用于MyISAM表,可以在Create Table時(shí)或之后使用Alter Table或Create Index在Char、VarChar或TEXT列上創(chuàng)建。對(duì)于大的數(shù)據(jù)庫(kù),將數(shù)據(jù)裝載到一個(gè)沒有FullText索引的表中,然后再使用Alter Table (或Create Index) 創(chuàng)建索引,這將是非常快的。
但是,眾所周知,在英文排版時(shí)詞間是以空格區(qū)分的,所以英文的分詞是基于空格的。但是涉及到中文等東亞文字就沒有這么簡(jiǎn)單了,因?yàn)橹形脑~間并沒有明顯的區(qū)隔,所以中文的分詞則是按照字典、詞庫(kù)的匹配和詞的頻度統(tǒng)計(jì),或是基于句法、語(yǔ)法分析的分詞,而MySQL并不具備此功能,所以MySQL對(duì)中文全文檢索的支持幾乎為零。
需求及設(shè)計(jì)思想
來(lái)自NetCraft統(tǒng)計(jì)的數(shù)據(jù),截至2006年4月份全球網(wǎng)站數(shù)量超過(guò)8065萬(wàn)個(gè),目前,Linux及Apache在網(wǎng)站操作系統(tǒng)及Web服務(wù)器軟件市場(chǎng)的份額為62.7%。再來(lái)看一份來(lái)自中國(guó)互聯(lián)網(wǎng)絡(luò)信息中心(CNNIC)的調(diào)查報(bào)告,截至2006年1月1日,全國(guó)有69.4萬(wàn)個(gè)網(wǎng)站,在線數(shù)據(jù)庫(kù)數(shù)為29萬(wàn)5400個(gè)。由于中國(guó)使用LAMP(Linux、Apache、MySQL、PHP)套件的數(shù)量沒有達(dá)到世界平均份額,所以估計(jì)有15萬(wàn)左右的基于PHP/MySQL構(gòu)架的網(wǎng)站,這不包括5萬(wàn)個(gè)WAP網(wǎng)站、企業(yè)管理系統(tǒng)、教學(xué)應(yīng)用系統(tǒng)等信息管理系統(tǒng)。如果全都算上,在中國(guó)使用MySQL的站點(diǎn)(系統(tǒng))數(shù)量應(yīng)該在15萬(wàn)至18萬(wàn)之間。
MySQL有如此龐大的使用規(guī)模,中文全文檢索在MySQL的實(shí)現(xiàn)將是相當(dāng)迫切,加之筆者在做一個(gè)網(wǎng)站系統(tǒng)的時(shí)候也是由于租用服務(wù)器硬性環(huán)境,不能自由選擇數(shù)據(jù)庫(kù)或者添加組件,所以只能根據(jù)已有的條件進(jìn)行適應(yīng)性改良。一個(gè)偶然的思路使筆者產(chǎn)生了能否將中文和英文建立特定關(guān)聯(lián),然后再進(jìn)行檢索呢?答案是可以的。MySQL不支持中文全文檢索,但是支持英文全文檢索,可以將“中文全文檢索”轉(zhuǎn)變?yōu)椤坝⑽娜臋z索”,然后再變回“中文全文檢索”。那么中文又如何轉(zhuǎn)換成英文呢?思路可以是:中文全文檢索→拼音全文檢索→中文全文檢索。所以轉(zhuǎn)換的思路如圖1所示。
圖1 中文全文檢索思路
用戶輸入中文信息提交的時(shí)候,通過(guò)一個(gè)中文到拼音的轉(zhuǎn)換程序?qū)⑵鋽?shù)據(jù)轉(zhuǎn)換為拼音的格式存入數(shù)據(jù)庫(kù)中,然后用戶檢索時(shí)同樣是輸入中文,也將檢索詞轉(zhuǎn)換為拼音,到數(shù)據(jù)庫(kù)中進(jìn)行匹配,返回結(jié)果。但是這樣做有兩個(gè)缺點(diǎn):第一個(gè)是,檢索是成功了,可是沒有中文原數(shù)據(jù),如何返回有效結(jié)果?第二個(gè)是,中文轉(zhuǎn)換拼音如果中文篇幅過(guò)長(zhǎng),轉(zhuǎn)換時(shí)間過(guò)長(zhǎng)怎么辦?所以催生了第二種解決方法,如圖2所示。
圖2 改進(jìn)后的檢索思路
如圖2所示,用戶輸入中文按照正常方式直接提交至數(shù)據(jù)庫(kù),然后有一個(gè)后臺(tái)轉(zhuǎn)換程序循環(huán)執(zhí)行,將中文轉(zhuǎn)換為拼音存入另外一張全文檢索表中,其他用戶在進(jìn)行全文檢索時(shí)由于詞語(yǔ)長(zhǎng)度有限,所以可以采用即時(shí)轉(zhuǎn)換拼音,然后進(jìn)行數(shù)據(jù)庫(kù)查詢匹配。
MySQL中文全文檢索實(shí)現(xiàn)
1.?dāng)?shù)據(jù)庫(kù)表結(jié)構(gòu)設(shè)計(jì)
此處用到兩張表,以為人員信息建立全文檢索為例,分為:人員信息表(UserInfo)和全文檢索表(IndexSeek),表結(jié)構(gòu)如圖3所示。
圖3 人員信息表和全文檢索表
人員信息表(UserInfo)各列含義為: ID(id),自增序列;姓名(user_name);個(gè)人介紹(user_introduction);全文檢索狀態(tài)(user_state),新添加或者修改后狀態(tài)為0,拼音轉(zhuǎn)換完成狀態(tài)為1。
全文檢索表(IndexSeek) 各列含義為:ID(id),自增序列;關(guān)聯(lián)人員信息ID(user_id),對(duì)應(yīng)UserInfo表中ID;索引項(xiàng)(index_item),該列設(shè)置為FullText全文檢索;索引標(biāo)示(index_mark),標(biāo)示為哪個(gè)列的索引,本文中涉及兩個(gè)索引,分別為姓名(user_name)、介紹(user_introduction)。
兩個(gè)表中的log字段記錄該行修改的時(shí)間和產(chǎn)生的錯(cuò)誤提示。在本文中無(wú)實(shí)際用途。
2.用戶輸入中文資料
用戶自己輸入信息添加至數(shù)據(jù)庫(kù),例如,各項(xiàng)為:“1”、“張三”、“愛好編程,PHP,MySQL”、“0”。
3.后臺(tái)轉(zhuǎn)換拼音過(guò)程
后臺(tái)應(yīng)用程序按照規(guī)則進(jìn)行中文到拼音的轉(zhuǎn)換,筆者在網(wǎng)上下載了內(nèi)碼→拼音轉(zhuǎn)換數(shù)據(jù)包pinyin.dat,該文件的下載網(wǎng)址為:http://scws.tguanlim.com/py/getpy.php。 以下以PHP代碼為例演示中文→拼音轉(zhuǎn)換。
//my_Getpy漢字轉(zhuǎn)換拼音類[5]
class my_Getpy
{
var $_dat = 'pinyin.dat';
var $_fd = false;
function my_Getpy($pdat = '')
{
if ('' != $pdat)
$this->_dat = $pdat;
}
function load($pdat = '')
{
if ('' == $pdat)
$pdat = $this->_dat;
$this->unload();
$this->_fd = @fopen($pdat, 'rb');
if (!$this->_fd)
{
trigger_error("沒有`$pdat`文件", E_USER_WARNING);
return false;
}
return true;
}
function unload()
{
if ($this->_fd)
{
@fclose($this->_fd);
$this->_fd = false;
}
}
function get($zh)
{
/*if (strlen($zh) != 2)
{
trigger_error("`$zh` is not a valid GBK hanzi", E_USER_WARNING);
return false;
}*/
if (!$this->_fd && !$this->load())
return false;
$high = ord($zh[0]) - 0x81;
$low = ord($zh[1]) - 0x40;
// 計(jì)算偏移位置
$nz = ($ord0 - 0x81);
$off = ($high< <

// 判斷 off 值
fseek($this->_fd, $off * 8, SEEK_SET);
$ret = fread($this->_fd,

$ret = rtrim($ret, '\0');
return $ret;
}
function _my_Getpy()
{
$this->_unload();
}
}
//截取字符函數(shù)
function csubstr($str,$start,$len)
{
$strlen=strlen($str);
if ($start>=$strlen)
return $str;
$clen=0;
for($i=0;$i< $strlen;$i++,$clen++)
{
if(ord(substr($str,$i,1))>0xa0)
{
if ($clen>=$start)
$tmpstr.=substr($str,$i,2);
$i++;
}
else
{
if ($clen>=$start)
$tmpstr.=substr($str,$i,1);
}
if ($clen>=$start+$len)
break;
}
return $tmpstr;
}
//計(jì)算字符長(zhǎng)度的函數(shù),漢字中文都當(dāng)作是長(zhǎng)度為1
function StrLenW($str)
{
$count = 0;
$len = strlen($str);
for($i=0; $i< $len; $i++,$count++)
if(ord($str[$i])>=128)
$i++;
return $count;
}
//批量中文轉(zhuǎn)換拼音函數(shù),轉(zhuǎn)換后每個(gè)字符中間加上空格,判斷非中文字符如符號(hào),英文,數(shù)字則不作變動(dòng)
function operate_py($str){
$len_max=StrLenW($str);
$len="0";
$start="0";
$py = new my_Getpy;
for($start=0;$start< $len_max;$start++){
$simp=csubstr($str,$start,$len);
if ( ord($simp)>127 ){
$rs = $py->get($simp);
$rs=" ".$rs." ";
}
else{
$rs=$simp;
}
$rs_return.=$rs;
}
$py=null;
return $rs_return;
}
將該程序循環(huán)執(zhí)行,查詢user_state為0的行,取出user_name、user_introduction兩列數(shù)據(jù),分別進(jìn)行拼音轉(zhuǎn)換,然后插入全文檢索表(IndexSeek)表中,添加兩行數(shù)據(jù),其中第一行為:
關(guān)聯(lián)人員信息ID(user_id):1;//對(duì)應(yīng)UserInfo表中ID,此處為1
索引項(xiàng)(index_item):zhang1 san1;
索引標(biāo)示(index_mark): 姓名(user_name)。
第二行為:
關(guān)聯(lián)人員信息ID(user_id):1;//對(duì)應(yīng)UserInfo表中ID,此處為1
索引項(xiàng)(index_item):ai4 hao3 bian1 cheng2 ,PHP,MySQL;
索引標(biāo)示(index_mark):介紹(user_introduction)。
至此,添加中文數(shù)據(jù)轉(zhuǎn)換拼音過(guò)程完畢。修改用戶信息同樣步驟進(jìn)行,只是不再新添加表,刪除數(shù)據(jù)則根據(jù)關(guān)聯(lián)id全部刪除。
4.用戶檢索過(guò)程
由于用戶檢索時(shí)輸入的關(guān)鍵詞數(shù)量有限,則采用頁(yè)面應(yīng)用程序直接轉(zhuǎn)換拼音進(jìn)行匹配。例如用戶輸入檢索詞為:“編程”,提交給服務(wù)器,由服務(wù)器端程序處理轉(zhuǎn)換為“bian1 cheng2”進(jìn)行數(shù)據(jù)表IndexSeek的全文檢索,全文檢索SQL為:
SELECT * FROM IndexSeekWHERE MATCH (index_item) AGAINST (' bian1 cheng2');
得出關(guān)聯(lián)人員ID為1,然后取得用戶資料表中全部信息返回給用戶。由于中文轉(zhuǎn)換拼音過(guò)程同上,在此不再列出代碼。
更多的英文全文檢索技巧請(qǐng)參看MySQL手冊(cè),這里不再一一介紹。上面便是整個(gè)MySQL中文全文檢索實(shí)現(xiàn)過(guò)程。
本文所提供的方法并不能完全解決MySQL的全文檢索問(wèn)題,由于中文字詞存在同音現(xiàn)象,比如:"清華"和"輕劃"檢索結(jié)果相同,這也是不可避免的,但是對(duì)于MySQL的用戶來(lái)說(shuō),該方法是目前不錯(cuò)的一種折衷手段。
(計(jì)算機(jī)世界報(bào) 2006年09月25日 第37期 B28、B29)
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
