2011-09-01 74 views
0

我試着去實施小的項目,人們可以爲某些項目和類似的標籤標籤將被顯示在頁面上。簡化SQL搜索

例如:

表:item_data 第1行:

item_id = 1 (event) 
Tags = "Rugby, Tickets, Give away, Sesssions, Prizes" 

行2:

item_id = 2 (Ticket booking) 
Tags = "New Zeland, Travel, Booking, Tickets, Rugby" 

行3:

item_id = 3 (car for sale) 
Tags = "New Zeland, Blue, Ford, Sedan" 

有遠純粹在SQL至爲給定的一組標籤獲取所有匹配的item_id。 從第1行獲取標籤數據,並找到所有其他行中每個標籤的所有匹配記錄?

我可以用PHP和MySQL的混合做到這一點,我想知道如果任何人有更好的方式來獨自做到這一點的SQL。

回答

1

我會建議使用數據標準化(http://www.bkent.net/Doc/simple5.htm)。如果你保持標籤的字符串格式,如「一個標籤,標籤B標籤c等」,那麼你必須選擇在數據庫中的每個標籤打破他們在陣列和爲了找到初步認識數據上不匹配。

我會建議做一個表的項目,另一個標籤作爲新標籤然後加入第三個表映射ITEM_ID的標籤將增長。完成此操作後,您可以選擇基於特定標籤和標籤組來獲取結果。

|Item_table    | 
|-------------------------| 
|item_id | Desc   | 
|1  | Event   | 
|2  | Ticket Booking | 
|-------------------------| 

|Tag_Table | 
|------------| 
|id | tag | 
|1 | Rugby | 
|2 | Blue | 

|Tag_Map     | 
|-------------------------| 
|id | tag id | item id | 
|1  | 1  | 1  | 
|2  | 1  | 2  | 

您將創建一個映射表的索引和標籤表格。你可以使用這個像這樣:

SELECT it.Desc FROM Item_Table it, Tag_Table tt, Tag_Map tm WHERE tt.id = tm.tag_id AND it.item_id = tm.item_id and (tt.tag = "Rugby" or tt.tag = "Blue"); 

你只需要在(最後一部分)更改爲一個標籤或繼續增加「或」,另一個標籤,這將使你的任何和所有的項目說明,這匹配任何給定的標籤。

我知道3個表看起來像很多管理但相信我,如果你的項目表和標籤表開始增長到成千上萬的你(和你的mysql服務器)將欣賞這種風格的數據存儲。

+0

這是我第一次想到的,但我們必須讓客戶輸入標籤。那麼我們必須打破這些標籤並將每個標籤作爲單個記錄插入,並檢查是否有重複記錄。 webbandit解決方案似乎相當簡單。獲取每個項目的標籤列表,使用'或者像%%'建立一個sql。 但是這會發生在每一頁的加載,所以我不知道對mysql服務器會有什麼影響。 – heshanh

+0

隨着表大小的增加,LIKE比較將在MySQL服務器上非常重要。你面臨的實際挑戰是規模。你要求MySQL在字段上進行字符串搜索。這是一個「重」的操作,您現在也必須搜索表格中的每一行以查找每個標籤。如果你有一百萬行並搜索3個標籤,那你已經完成了300萬行處理。如果您使用我的方法,它將使用索引來消除不需要的行,並大幅減少查詢時間。如果你只有500行,沒有biggy使用LIKE。但是隨着時間的推移,你會希望你使用正常的形式。 – Wrenbjor

+0

我明白你的觀點。在查看數據庫後,我們有大約300-600行。我不認爲它會達到數以百萬計的最大數據集,我們可能最終以1000行,但它不太可能。 但對於未來的擴展,這似乎是最好的方法。我與開發團隊的其他人聊天,看看他們想如何去做。 感謝您的信息:) – heshanh

0
SELECT * FROM TABLE WHERE `Tags` LIKE %Rugby% OR `Tags` LIKE %New Zeland% OR ..... 

會告訴你在Tag裏有'Rugby'或'New Zeland'或...的所有行。

您可以創建存儲過程,並通過搜索「標籤」給它。在過程中創建正確的SQL QUERY。