2010-05-15 78 views
2
  1. 標籤(id_tag,名稱)
  2. 消息(ID,標題,數據,標籤)

字段消息>標記VARCHAR(255)。林規劃把數據像這樣在這一領域:「1,7,34MYSQL:如何搜索字段,保持價值sep。通過逗號?

這意味着,在新聞特定行鏈接到從標籤表標籤1,7和34。

的話,我怎麼可以搜索ALL新聞記錄中有值(其中包括)在標籤場?

有沒有更好的方法來做到這一點?

+0

把標籤放入varchar只是一個等待發生的問題。你應該有另一個包含(news_id,tag)值的表 – 2010-05-15 01:27:48

回答

4

你可以完全通過增加第三臺NewsTags(PKID,news_ID,TAG_ID)規範化表的設計正是如此填充它(假設你的榜樣新聞記錄是記錄100):

1, 100, 1 
1, 100, 7 
1, 100, 34 

然後,對於「如何」你的問題的一部分,你會加入到新聞標籤的新聞標籤,哪裏Tags.TagID = 34

試試看;我相信一些示例代碼將遵循..

3

有一種方法可以做到這一點。你可以做線沿線的東西:

select id from news where ','||tags||',' like '%,34,%' 

或:

select id from news where tags like '34,%' 
union all select id from news where tags like ',34%' 
union all select id from news where tags like '%,34,%' 

但是這將是資源的一個可怕的豬(以及面色難看),因爲你可以列沒有索引部分。選擇查詢中的每行函數從不能很好地擴展。

方式做,這是一個以逗號分隔值分離出來,並按照第三範式(3NF) - 所有有抱負的DBA真的應該閱讀了關於這個概念應該誰希望所有的程序員一起工作,瞭解數據庫:

tags: 
    id_tag 
    name 
    primary key (id_tag) 
news 
    id 
    title 
    data 
    primary key (id) 
news_tags 
    id   foreign key news(id) 
    id_tag  foreign key tags(id_tag) 
    primary key (id,id_tag) 
    index  (id_tag) 

然後你可以用這樣的查詢:

select n.id from news n, news_tags nt 
    where nt.id_tag = 34 
     and n.id = nt.id 

(或者其明確的聯接當量)。這將允許DBMS有效地使用您爲所有表設置的索引。

你應該從來沒有把自己放在你需要使用任何東西的一部分列的情況下,因爲這固有地破壞了可伸縮性。通過將標籤分離成單獨的列(並通過引入另一個表使它們成爲真正的多對多關係),可以消除該問題。

所有數據庫都應該在3NF中構建,並且只有在性能問題出現時纔會恢復,並且只有在瞭解後果時纔會恢復。在這些情況下,您可以使用一些技巧來確保數據完整性(例如插入/更新觸發器),但對於初學者,我建議堅持使用3NF。