【发布时间】:2010-09-14 05:08:49
【问题描述】:
假设我在 MySQL 数据库中有一个图书表,并且我想在“标题”字段中搜索关键字(由用户在搜索字段中输入);在 PHP 中执行此操作的最佳方法是什么? MySQL LIKE 命令是最有效的搜索方式吗?
【问题讨论】:
假设我在 MySQL 数据库中有一个图书表,并且我想在“标题”字段中搜索关键字(由用户在搜索字段中输入);在 PHP 中执行此操作的最佳方法是什么? MySQL LIKE 命令是最有效的搜索方式吗?
【问题讨论】:
是的,最有效的方法通常是在数据库中搜索。为此,您有三种选择:
因此,这取决于您将实际搜索什么来决定什么是最好的。对于书名,我会提供 LIKE 搜索来精确匹配子字符串,这在人们知道他们正在寻找的书时很有用,并且还提供 FULLTEXT 搜索来帮助查找与单词或短语相似的标题。当然,我会在界面上给它们起不同的名称,可能类似于子字符串搜索的确切名称和全文搜索的类似名称。
全文示例:http://www.onlamp.com/pub/a/onlamp/2003/06/26/fulltext.html
【讨论】:
这是一种简单的方法,您可以拆分一些关键字以构建一些子句,以过滤这些关键字上的列,可以是 ANDed 或 ORed。
$terms=explode(',', $_GET['keywords']);
$clauses=array();
foreach($terms as $term)
{
//remove any chars you don't want to be searching - adjust to suit
//your requirements
$clean=trim(preg_replace('/[^a-z0-9]/i', '', $term));
if (!empty($clean))
{
//note use of mysql_escape_string - while not strictly required
//in this example due to the preg_replace earlier, it's good
//practice to sanitize your DB inputs in case you modify that
//filter...
$clauses[]="title like '%".mysql_escape_string($clean)."%'";
}
}
if (!empty($clauses))
{
//concatenate the clauses together with AND or OR, depending on
//your requirements
$filter='('.implode(' AND ', $clauses).')';
//build and execute the required SQL
$sql="select * from foo where $filter";
}
else
{
//no search term, do something else, find everything?
}
【讨论】:
考虑使用sphinx。它是一个开源的全文引擎,可以直接使用你的 mysql 数据库。它比手动编码 LIKE 语句更具可扩展性和灵活性(并且更不容易受到 SQL 注入的影响)
【讨论】:
您也可以在 mysql 手册http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_soundex 中查看 soundex 函数(soundex,听起来像) 如果严格检查(通过 LIKE 或 =)没有返回任何结果,则返回这些匹配项的功能。
【讨论】:
Paul Dixon 的代码示例很好地理解了基于 LIKE 的方法的主要思想。
我只是添加这个可用性想法:在界面中提供一个(AND | OR)单选按钮,默认为AND,然后如果用户的查询结果为零(0)匹配并且包含至少两个单词,则响应带有一个选项:
“抱歉,没有找到与您的搜索词组匹配的。扩展搜索以匹配您的词组中的任何单词?
也许有更好的表达方式,但基本思想是引导人们进行另一个查询(可能会成功),而用户不必考虑布尔逻辑AND 和 OR。
【讨论】:
我认为如果是一个词,Like 是最有效的方式。如前所述,可以使用explode功能拆分多个单词。然后它可以循环并用于在数据库中单独搜索。如果两次返回相同的结果,可以通过将值读入数组来检查。如果它已经存在于数组中,则忽略它。然后使用计数功能,您将知道在循环打印时在哪里停止。可以使用similar_text 函数进行排序。百分比用于对数组进行排序。这是最好的。
【讨论】: