2012-11-16 52 views
2

一个简单的问题是preg_match在PHP中与like在mysql中查询是一样的吗?与两个表之间的mysql模式比较列

主要问题:

考虑以下是我的两个表Table 1和Table

表1                                                                                                                                           表2

 
+-------+-------------------------+  +-------+------------------------------+ 
| ID | Model     |  | ID | Model      | 
+-------+-------------------------+  +-------+------------------------------+ 
| 1  | iPad 2 WiFi 16GB  |  | 1  | iPad2 WiFi 16GB    | 
| 2  | iPhone 4S 16GB   |  | 2  | iPhone4S 16GB    | 
| 3  | iPod Touch(4th Gen)8GB |  | 3  |iPod Touch 4th Generation 8GB | 
+-------+-------------------------+  +-------+------------------------------+ 

现在我要做的是将这两个表进行比较,你可以看到iPad 2 WiFi 16GBiPad2 WiFi 16GBiPod Touch(4th Gen)8GBiPod Touch 4th Generation 8GB都是相同的,但它不显示,如果我把我的查询where Table1.model = Table2.model,因为他们是完全匹配。我想要做的是通过使用like或其他任何方式将这些行与mysql查询进行比较,以便比较两个相似的表格行。请让我知道如何编写这样的SQL查询。

我试过下面的sql查询,但它没有返回所有行,就像它没有返回上面例子中提到的那些行类型。

SELECT table1.model as model1, table2.model as model2 
FROM table1,table2 WHERE table1.model REGEXP table2.model 
+2

阅读一些有关'FULLTEXT Search'也许它可以帮助你。 –

+0

通常这种事情是通过第三个表格来完成的,第三个表格有'关键词'和一个表格,可以将这些表格与您的表格匹配。每行一个关键字然后对此进行加入,并按照点击次数进行排名。 – ethrbunny

+1

@JohnWoo好吧我会看看它..... –

回答

1

有两个问题 - 标准描述(说明不变)还是由用户输入?如果它们是标准的,则添加一个整数列并对该列进行比较。

如果它是由用户输入的,你的工作更复杂,因为你正在寻找一些更模糊的搜索。我使用了二元搜索算法对两个字符串之间的相似性进行排序,但这不能直接在mySQL中完成。

代替模糊搜索,您可以使用LIKE,但如果您最终将'%'放在搜索词的开头,它的效率仅限于进行表扫描。另外,它意味着你可以在你选择的子串部分获得一个匹配,这意味着你需要提前知道子串。

我很乐意多一次,我知道你要怎样做详细说明。

EDIT1:好吧,给你的阐述,你需要做一个模糊风格的搜索,因为我提及。我使用的是一种双元方法,它涉及将用户输入的每个条目分成2或3个字符的块。然后,我将这些块存储在另一个表中,每个条目都回到实际描述中。

例子:

内容描述: “向前快速奔跑” 广告描述: “前进短期内”

如果你打破每进2字符块 - 'A', 'F',“发”,‘为’,‘ST’.....

然后你就可以比较匹配两个字符串,并得到一个‘分数’说,这将意味着两者之间的准确性或相似2字符块数。

由于我不知道你正在使用什么开发语言,我会离开的实施,但是这一点是需要将没有明确的MySQL的完成。

或者懒惰的选择是使用像亚马逊这样的云搜索服务,它会根据您提供的条款提供搜索...不确定他们是否允许您不断添加新的描述来考虑,并且取决于你的应用程序,它可能有点贵(恕我直言)。

[R

对于另一SO张贴在二元实施 - 看到这个SO bigram/fuzzy search

---每提问阐述更新---

首先,我假设你在阅读理论我提供的链接。第二,我会尽可能保持数据库不可知,因为它不需要mySQL(尽管我使用它,它的工作原理还不错)

好吧,方法在制作/比较内存时工作正常数组只有在可能的匹配相对较小的情况下才会发生,否则它会遭受表扫描性能的影响,就像一个没有索引的mysql表格一样快。所以,你要利用数据库的优势来为你做索引。

你需要的是一个表来保存用户输入的“条款”或文字,你要找比较。最简单的形式是两列的表,一个是一个独特的自动递增整数将被编入索引,我们将在下面叫hd_id,第二个是一个varchar(255)如果字符串很短,或TEXT如果他们能变长 - 你可以任意命名。

然后,您需要创建另一个至少包含THREE列的表 - 一个用于引用列返回到另一个表的自动递增列(我们将在下面称这个hd_id),第二个表为最多5个字符的varchar()(这将保存你的bigram块),下面我们将它称为“bigram”,第三个是自动递增列,名为b_id。这个表格将为每个用户的条目保存所有条目,并与整个条目相关联。您需要自行索引varchar列(或者先在复合索引中按顺序)。

现在,每次用户输入要搜索的术语时,都需要在第一个表中输入术语,然后将术语解剖为bigrams,然后使用引用将每个片段输入到第二个表中在第一个表的总体条款中完成关系。这样,你就可以在PHP中进行解析,但让MySQL或任何数据库为你做索引优化。在计算阶段,它可能有助于在两阶段存储表1中所做的两个bigrams。下面是一些在PHP代码给你如何创建双字母组一个想法:

// split the string into len-character segments and store seperately in array slots 
function get_bigrams($theString,$len) 
{ 
    $s=strtolower($theString); 
    $v=array(); 
    $slength=strlen($s)-($len-1);  // we stop short of $len-1 so we don't make short chunks as we run out of characters 

    for($m=0;$m<$slength;$m++) 
    { 
     $v[]=substr($s,$m,$len); 
    } 
    return $v; 
}  

不要担心在串空间 - 它们实际上是,如果你想模糊搜索真的很有帮助。

所以你得到了bigrams,把它们输入到一张表中,通过索引列链接到表1中的整体文本......现在呢?

现在,只要搜索“我最喜欢的术语搜索”这样的术语,就可以使用php函数将它转换为一个bigrams数组。然后,您可以使用它在您的bigram表(2)上创建SQL语句的IN(..)部分。下面是一个例子:

select count(b_id) as matches,a.hd_id,description, from table2 a 
inner join table1 b on (a.hd_id=b.hd_id) 
where bigram in (" . $sqlstr . ") 
group by hd_id order by matches desc limit X 

我已经离开了$ sqlstr作为PHP字符串引用 - 你能够构建这自己作为一个逗号使用破灭或get_bigrams返回无论阵列或者分离二元函数列表如果你也喜欢参数化。

如果处理正确,上面的查询返回最匹配的模糊搜索条件,具体取决于您选择的两个bigram的长度。您选择的长度具有基于您预期的总体搜索字符串长度的相对效力。

最后 - 上面的查询,只是给出了模糊匹配排名。你可以通过比较不仅仅是比赛来进行比赛,而是通过比较来进行提高,但是匹配与总体双重计数相比,这将有助于减少长字符串的搜索字符串长度。我已经停下来了,因为在这个时候它变得更具有特定的应用程序。

希望这会有所帮助!

[R

+0

模型是由用户输入,所以我必须匹配和提取,如果他们的意思是相同的。如果他们喜欢“iPod Touch(第4代)8GB”和“iPod Touch第4代8GB”,并且它们含有相同的含义,所以它们都是一样的。我必须以这种方式进行比较。 –

+0

这里是一个简单的版本搜索答案的链接,但基于你的阐述,我不认为这会做。 http://stackoverflow.com/questions/3276904/mysql-conduct-a-fuzzy-search – Ross

+0

我正在使用PHP,请让我知道bigram的工作方式或完全'similar_text或Levenshtein或metaphones'在PHP? –