2012-11-16 50 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? –