阅读量:0
MySQL数据库对dvbbs.php全文搜索的完全分析,需要先了解dvbbs.php文件的结构,然后针对其中的数据表进行索引优化、查询优化等操作。
MySQL全文搜索基础
MySQL提供了强大的全文搜索功能,可以用于在文本字段中执行复杂的自然语言搜索,其核心是使用MATCH()
和AGAINST()
函数,基本语法如下:
SELECT * FROM table_name WHERE MATCH(col1, col2, ...) AGAINST('search_string');
在文章表中搜索标题和正文包含“database”的记录:
SELECT * FROM articles WHERE MATCH (title, body) AGAINST ('database');
复杂查询与排序
为了实现更复杂的功能,比如返回相关值并按相关性排序,可以在SELECT
列表和WHERE
子句中各指定一次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');
中文全文搜索的挑战
MySQL本身不支持CJK(中文、日文、韩文)的分词,因此需要借助PHP等语言进行模拟分词,中文分词是语言分词中最困难的部分,目前还没有完美的解决方案。
PHP模拟中文分词
在PHP中,可以使用自定义函数来模拟中文分词,以下是一个示例函数DV_ChineseWordSegment
,它通过过滤HTML标签和停用词,然后逐字拆分字符串来实现简单的分词:
function &DV_ChineseWordSegment($str, $encodingName = 'gbk') { static $objEnc = null; if ($objEnc === null) { if (!class_exists('DV_Encoding')) { require_once ROOT_PATH . 'inc/DV_Encoding.class.php'; } $objEnc =& DV_Encoding::GetEncoding($encodingName); } $strLen = $objEnc>StrLength($str); $returnVal = array(); if ($strLen <= 1) { return $str; } $arrStopWords =& DV_GetStopWordList(); $str = preg_replace('#<[azAZ]+?.*?>|#is', '', $str); // 过滤所有HTML标签 $str = str_replace($arrStopWords['StrRepl'], ' ', $str); // 过滤所有停用词 $str = preg_replace($arrStopWords['PregRepl'], ' ', $str); $arr = explode(' ', $str); foreach ($arr as $tmpStr) { if (preg_match("/^[x00x7f]+$/i", $tmpStr) === 1) { // 全是英文字符 $returnVal[] = ' ' . $tmpStr; } else { // 中英混合 preg_match_all("/([azAZ]+)/i", $tmpStr, $matches); if (!empty($matches)) { // 英语部分 foreach ($matches[0] as $matche) { $returnVal[] = $matche; } } $tmpStr = preg_replace("/([x00x7f]+)/i", '', $tmpStr); // 过滤ASCII字符 $strLen = $objEnc>StrLength($tmpStr) 1; for ($i = 0; $i < $strLen; $i++) { $returnVal[] = $objEnc>SubString($tmpStr, $i, 2); // 注意这里的substr用法 } } } return $returnVal; }
FAQs
Q1: MySQL全文搜索中哪些词会被忽略?
A1: 在MySQL全文搜索中,任何过于短的词(默认最小长度为4个字符)和停止字中的词都会被忽略。
Q2: PHP如何模拟中文分词以支持MySQL全文索引?
A2: PHP可以通过自定义函数如DV_ChineseWordSegment
来模拟中文分词,该函数首先过滤HTML标签和停用词,然后将字符串逐字拆分,对于中英混合的情况,先提取出英文部分,再处理剩余的中文部分。