2016-08-31 56 views
0

假設我有一個表格,其中一列標題的數據是用逗號分隔的數據。在mysql表中搜索標籤的更好方法

"tag1,tag2,new york,tag4" 

正如你所看到的,一些標籤會有空格。

對於任何等於「紐約」的標籤,查詢表格的最佳或最準確的方法是什麼?

在過去,我已經使用:

SELECT id WHERE find_in_set('new york',tags) <> 0 

但當值具有空間FIND_IN_SET不起作用。目前我使用這個

SELECT id WHERE concat(',',tags,',') LIKE concat(',%new york%,') 

但我不知道這是最好的辦法。

你會怎麼做?

+0

在第二個方法的問題是什麼,如果你有一個像'tag1'和'tag10',如果你倆返回true標籤搜索'tag1'。 – FrozenFire

+0

嗯,是的 - 這確實是一個問題。 – Strawberry

+0

確切地說,不知道如何繼續。 – DanielOlivasJr

回答

2

當項A可以與許多項目B相關聯,並且B項可以與許多項目A.這被稱爲Many to many relationship

與這些關係的數據相關聯應存儲在單獨的表中,僅連接在一起在查詢。

Examble

表1

| product_uid | price | amount | 
|  1  | 12000 | 3000 | 
|  2  | 30000 | 600 | 

表2

| tag_uid | tag_value | 
| 1 | tag_01 | 
| 2 | tag_02 | 
| 3 | tag_03 | 
| 4 | tag_04 | 

然後我們使用一個連接表爲涉及他們

表3

| entry_uid | product_uid | tag_uid | 
| 1  |  1  |  3 | 
| 2  |  1  |  4 | 
| 3  |  2  |  1 | 
| 4  |  2  |  2 | 
| 5  |  4  |  2 | 

查詢將是(如果你想選擇一個項目和標籤)

SELECT t1.*, t2.tag_value 
FROM Table1 as t1, 
JOIN Table3 as join_table ON t1.product_uid = join_table.product_uid 
JOIN Table2 as t2 ON t2.tag_uid = join_table.tag_uid 
WHERE t1.product_uid = 1 
+0

從經驗來看,這在小數據集上工作良好,但加入大數據集確實可以使數據庫達到最佳狀態。它真的是最有效的方法嗎? – Damien

+0

如果您規範化您的數據庫(規範化意味着我上面使用的方法),從表中選擇需要稍長的時間,但它只需要一個條目來更新記錄。如果你沒有規範化數據庫,選擇會快一點,但是在更新表時你需要更新多個條目。有些情況下,數據庫沒有正常化是有意義的,例如日誌或事務歷史記錄,但大多數時候我會打賭,它處理數據不一致性更好。閱讀更多信息:https://www.thoughtco.com/should-i-normalize-my-database-1019730 –

0

如果我需要忽略tags中逗號前後的前導空格。

例如,如果tags過的值:

'atlanta,boston , chicago, los angeles , new york ' 

並假設空間是我想忽略的唯一的性格,我在尋找的標籤沒有任何開頭或結尾空格,那麼我可能會使用正則表達式。事情是這樣的:

SELECT ... 
    FROM t 
WHERE t.tags REGEXP CONCAT('^|, *', 'new york' ,' *,|$') 

我建議比爾Karwin的優秀圖書「SQL反模式:避免數據庫編程的陷阱」

https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557

第2章亂穿馬路涵蓋逗號的反模式分隔列表。