2010-05-15 23 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。