我在MySQL数据库的“地址”表中有地址。该表包含一个地址ID列和通常与地址相关的列 - 名称,第1行,第2行,郊区,州,邮政编码等。许多字段允许NULL。
这用于客户端基于Web的界面 - 用户可以通过在文本框中键入任何部分来查找并从表中选择地址。显示匹配项,用户可以选择一个。
文本框中的术语被视为以空格分隔的一系列搜索术语,并且每个术语必须出现在任何地址字段中,以便显示以供选择。
我在这几个实现方法之间徘徊:
目前的方法:
这种方法的好处是只需要发送一个简单的查询,并且在搜索字段和查看响应之间没有延迟,因为搜索是在客户端完成的(尽管这可能无法很好地扩展 - 见下文)。它还避免了复杂的SQL搜索的需要(我不反对,我只是想实现一些东西作为概念证明,这种方法更快)。
缺点当然是页面必须在加载页面时检索每个地址,并且数据库可能最终存储数千个地址。
另一种方法是在用户键入文本框时发送HTTP请求,这将返回与使用SQL搜索表匹配的地址。需要更多请求和更多延迟,但每次只需要检索和传输地址子集。我可以根据需要轻松调整最小术语长度和轮询频率。
我想知道实现这个SQL方面的最佳方法......
我最好创建一个视图,它连接所有可搜索的地址列,并使用带有WHERE子句的查询,沿着“concatcolumn LIKE'%term1%'和concatcolumn LIKE'%term2%'和concatcolumn LIKE'% termN%'“?
非常感谢任何想法或建议。
答案 0 :(得分:2)
我已经找到了一个我非常满意的解决方案。
首先创建一个包含连接的可搜索地址字段的视图:
CREATE VIEW address_concat AS
SELECT address_id, CONCAT_WS(' ', address_name, address_line_1, address_line_2, suburb, postcode, state, country) AS full_address
FROM address
当收到带有搜索字符串的请求时,我在PHP中解析它并使用视图查找匹配项(清除以下代码并删除不相关的内容 - 数据已清理等):
$terms = explode(' ', preg_replace('/\s+/', ' ', $_GET['find_address'])); //get array of terms
$where = " WHERE full_address LIKE '%".implode("%' AND full_address LIKE '%", $terms)."%' "; //turn array into WHERE clause
//query database to find matches
$result = $db->query("SELECT a.* FROM address a JOIN address_concat ac ON a.address_id = ac.address_id ".$where." ORDER BY IFNULL(IF(address_name = '', NULL, address_name), address_line_1)");
if ($result->num_rows > 0)
{
//construct output
$output = '<ul>';
while ($row = $result->fetch_assoc())
$output .= '<li val_id="'.$row['address_id'].'">'.make_address(...).'</li>';
$output .= '</ul>';
}
else
$output = '<p>No matches found.</p>';
在客户端,我使用了来自other questions的一些智慧,只是在打字暂停后才进行查询。
var typingTimer;
$('input#filterbox').bind('input', function ()
{
var textfield = $(this);
//code to hide/show "clear text field" box eliminated, etc
clearTimeout(typingTimer);
typingTimer = setTimeout(function () {doFilterUpdate(textfield);}, 750);
});
function doFilterUpdate (target)
{
if (target.val().length >= 3)
$('div#resultlist').load('inc/ajax.php?find_address=' + encodeURIComponent(target.val()));
else
$('div#resultlist').html('');
}
我仍然不确定创建视图是否必要/更有效,而不仅仅是在WHERE子句中使用CONCAT_WS的地址表上编写查询...它确实使查询更加简单,但是: p
答案 1 :(得分:0)
绝对不要在搜索之前带回地址,用户不会介意返回结果所需的第二个,使用加载gif来显示你的ajax调用期间发生的事情。
做类似的事情:
SELECT columns
FROM table
WHERE searchterm LIKE '%' + column1 + '%'
OR searchterm LIKE '%' + column2 + '%'
OR searchterm LIKE '%' + column3 + '%'
我也很想使用REPLACE
函数删除空格,逗号和句号
REPLACE(REPLACE(REPLACE(searchterm,' ',''),',',''),'.','') LIKE '%' + column1 + '%'
我也很想在查询结束后使用关键字LIMIT对结果返回的数量进行限制。