在制定查询以便在自动填充表单(jquery Axax + PHP)中使用时,我对SQL最佳实践有疑问。
让我们假设以下内容:
因此,用户将在开头使用“The”输入书名,或者只是省略“The”并在没有任何明确文章的情况下开始查询。
似乎存在三种可能的查询:
SELECT 'title' FROM 'books' WHERE 'title' LIKE '%$string'
或
SELECT 'title' FROM 'books' WHERE 'title' LIKE '$string%'
或
SELECT 'title' FROM 'books' WHERE 'title' LIKE '%$string%'
当使用第一个查询方法(%在字符串之前)时,很难得到任何结果,因为字符串之前的通配符似乎行为错误。
使用第二个查询时,似乎赞成在标题前使用“The”的完全匹配。因此,搜索“麦田里的守望者”的用户会找到这本书,但搜索“麦田里的守望者”的用户不会。
最后一个结果是最好的结果,因为它在字符串之前和之后都有一个通配符。但是,它也提供了最长的自动完成列表。用户必须输入几个字母才能缩小搜索结果范围。
有关实施更高效查询的任何想法?或者第三种选择是最好的选择(因为将书中的定冠词分开是不可行的?
提前致谢,
答案 0 :(得分:2)
您可以使用正则表达式进行搜索(查询结果很快就会出现) 并且不要忘记为结果添加限制。
一个小例子
SELECT title FROM books WHERE title REGEXP '$string' LIMIT 20
或者您可以使用字边界
SELECT title FROM books WHERE title REGEXP '[[:<:]]$string[[:>:]]' LIMIT 20
答案 1 :(得分:1)
我建议在字符串的两边使用带有通配符的第三种方法。如果您担心返回结果集的大小,可能会将结果限制为某个数字,并且当用户键入列表时,自然会变得更小,更具体。
答案 2 :(得分:1)
您也可以考虑允许搜索仍应匹配的“捕手黑麦”。
在这种情况下 - 你会标记标题中的每个单词以及用户输入的单词并找到最佳匹配。
否则仅在输入4个或更多字符后自动完成,并使用选项3。
答案 3 :(得分:1)
$query = mysqi_query("SELECT title FROM books WHERE title REGEXP '$string'");
if($query->num_rows() == 0) {
//First remove all the stop words like for, the, of, a from the search string.
$stopWords = array('/\bfor\b/i', '/\bthe\b/i', '/\bto\b/i', '/\bof\b/i','/\ba\b/i');
$string = preg_replace($stopWords, "", $string);
//Then, use
mysqli_query("SELECT title FROM books WHERE title REGEXP '$string'");
}
答案 4 :(得分:0)
如果您担心建议的数量,是否可以将更改事件修改为仅在字段中输入了一些最小字符数后检索建议?