2012-04-10 78 views
0

我有包含圖片和標籤(稱爲tbl_images)的表MySQL的標籤搜索

image_file image_tags 
---------- ---------------------------- 
test.png  tag1 another_tag tag2 
hi.jpg  tag9 tag1 another_tag qwerty 

我怎麼會做這麼說:

  • 搜索「另一個」沒有返回
  • 搜索'tag1'返回test.png行
  • 搜索'tag1 another_tag'返回test.png行
  • 'qwerty tag2'搜索沒有任何結果

正如在,能夠搜索使用完整標籤名稱,並同時搜索多個標籤,如果他們都出現在同一行中相同的image_tags字段。 注: -

  • 我只有一個字段內搜索
  • 它被用PHP搜索輸入(在$_GET['search_terms']檢索)
  • 我不能這樣做,因爲LIKE '%tag9%可能tag9中出現較大的做標籤,如Atag98,正如我所說我只會喜歡確切標籤匹配。
  • 我不能做LIKE ' tag9 '(前後注意空格,),因爲tag9可能出現在image_tags字段的開頭(那裏沒有空間,所以就沒有比賽)
  • 我不能做LIKE 'tag9 another_tag',因爲我不知道another_tag是在tag9之後出現的,同樣因爲同樣的原因我不能做LIKE 'tag9%another_tag';也tag9可能是較大的標記的一部分(如前所述)。

此外,是全文搜索適合這?如果是這樣,你能舉個例子嗎?

一個棘手的問題(無論如何;)任何幫助將不勝感激。

+2

你是在這張桌子上設計的嗎?理想情況下,您可以將圖像標記與圖像ID一起放入聯結表中,然後執行聯合以將其拉出。通過這種方式,MySQL不必使用強大的LIKE解析通過單獨的行 - http://stackoverflow.com/questions/5812680/many-to-many-relationship – citizenen 2012-04-10 22:28:12

+0

它似乎不適用於我。我將如何使用查詢來查找結果?我嘗試過:'SELECT * FROM images JOIN tags on tags.image_id = images.id WHERE tag ='hello''它返回帶有hello標籤的圖像,但是當我有多個標籤時這不起作用。 'WHERE tag ='hello'OR tag ='flowers''如果圖片在標籤表中的id旁邊有'hello'和'flowers'標籤,但是'WHERE tag ='hello'OR tag ='tag_doesnt_exist''會返回包含圖片的行,即使圖片沒有'tag_dosent_exist'標籤。 – q3d 2012-04-10 22:43:04

+0

如果你想要圖像有兩個標籤,使用'AND':'WHERE tag ='hello'AND tag ='tag_doesnt_exist'' – bfavaretto 2012-04-10 22:55:30

回答

7

存儲帶圖像標籤的更好解決方案是創建一個單獨的表格,其中標籤鏈接到圖像。然後您會爲每個標籤創建一行,例如

image_file (FK) tag 
--------------- ----------- 
test.png   tag1 
test.png   another_tag 
test.png   tag2 
hi.jpg   tag9 
hi.jpg   tag1 
hi.jpg   another_tag 
hi.jpg   qwerty 

然後,您可以簡單地查找該標籤與圖像有關的:

SELECT tag FROM tags WHERE image_file = 'test.png' 

或圖像與某個標籤:

SELECT image_file FROM tags WHERE tag = 'tag1' 

所有問題,喜歡哪個你在你的問題中描述的是用這種方法避免的。正常化數據庫時不需要全文搜索。

+0

我過度簡化了表結構,每一行都有一個唯一的用於搜索的Id和用於計數的其他列(如用戶名),我需要選擇數據並顯示它;這似乎並不適合我的需求。謝謝 – q3d 2012-04-10 22:28:13

+1

@iyrag,這是一個很好的答案(非常類似於上面評論中提到的聯結表方法)。如果你有很多領域並不重要,你可以使用連接來抓取所有東西。 – bfavaretto 2012-04-10 22:40:39

+0

在選擇帶有條件的所有圖像時,我無法使用此方法。另外,如果用戶有50個標籤,則會創建50個以上的行,這樣做效果不佳,效率非常低。如果相同的標籤在不同的圖像中多次使用過,會怎麼樣? – q3d 2012-04-10 22:50:02

2

對於您的標籤沒有明確的分隔符,您需要進行正則表達式選擇。

SELECT * FROM tbl_images WHERE image_tags REGEXP '[[:<:]]tag[[:>:]]' 

的[[:<:]]和[[:>:]]標記識別MySQL的單詞邊界......所以當一個正則表達式的選擇可能會比喜歡慢一些,這仍然可以工作。

瞭解更多關於MySQL的正則表達式的位置:http://dev.mysql.com/doc/refman/5.1/en/regexp.html

+0

tnx,很高興知道 – 2017-11-06 13:08:49

0

如果所有的標籤用空格分隔,爆炸他們到一個數組,然後搜索您所查找的關鍵字的數組。如果找到該關鍵字,則取該行。

我不知道你在這裏使用的語言是應該如何去:

loop all rows: 
    get values of the current row: 
    tags = array of the tags cell, explode ' ' 
    foreach (tag in tags): 
     if (tag == keyword) 
     save current row info 
    end foreach; 
end loop; 

你並不需要創建一個新的行對於每個標籤,就像一個在這裏建議,因爲這是不是一個理想的選擇。