【发布时间】:2010-02-05 16:46:45
【问题描述】:
我的表格中有一个字段用于标记某些内容,用空格分隔,目前我正在使用:
SELECT * FROM content WHERE tags LIKE '%$selectedtag%'"
但是如果选择的标签是elephant,它会选择带有bigelephant和elephantblah等标签的内容...
如何让它精确地选择我想要的东西?
【问题讨论】:
我的表格中有一个字段用于标记某些内容,用空格分隔,目前我正在使用:
SELECT * FROM content WHERE tags LIKE '%$selectedtag%'"
但是如果选择的标签是elephant,它会选择带有bigelephant和elephantblah等标签的内容...
如何让它精确地选择我想要的东西?
【问题讨论】:
SELECT * FROM content WHERE tags RLIKE '[[:<:]]elephant[[:>:]]'
如果你的表是MyISAM,你可以使用这个:
SELECT * FROM content WHERE MATCH(tags) AGAINST ('+elephant' IN BOOLEAN MODE)
,可以通过在其上创建FULLTEXT 索引来大幅改进:
CREATE FULLTEXT INDEX ix_content_tags ON content (tags)
,但即使没有索引也可以工作。
为此,您应该调整 @@ft_min_wold_len 以索引长度少于 4 个字符的标签(如果有的话)。
【讨论】:
你可以使用 MySQL 的正则表达式。
SELECT * FROM content WHERE tags REGEXP '(^| )selectedtag($| )'
但请注意,使用正则表达式会增加开销,并且在某些情况下可能表现不佳。
如果您可以更改数据库数据,另一种简单的方法是确保在第一个标记之前和最后一个标记之后有一个空格;有点像:“大象动物”。这样你就可以使用通配符了。
SELECT * FROM content WHERE tags LIKE '% selectedtag %'
【讨论】:
我会在这里考虑不同的设计。这构成了多对多关系,因此您可以有一个tags 表和一个连接表。一般来说,数据的原子性可以让您免去很多麻烦。
这种方法的另一个好处是您可以重命名标签,而无需编辑包含该标签的每个条目。
【讨论】:
A:你必须创建一个单独的标签表,它指向带有 contentid 的内容并包含一个关键字,然后:
select a.*
from content a,tags b
where a.id=b.contentid
group by a.id;
B:在标签之间和之前和之后加逗号,例如",bigelephant,elephant,",然后使用like "%,elephant,%"
【讨论】:
WHERE tags LIKE '% '{$selectedtag}' %'
OR tags LIKE ''{$selectedtag}' %'
OR tags LIKE '% '{$selectedtag}''
【讨论】:
'%' 是 SQL 中的通配符。去掉通配符,你会得到你想要的。
【讨论】:
重做表格设计,但现在如果你使用空格来分隔标签,你可以这样做:
SELECT * FROM content WHERE tags LIKE '% elephant %';
只要确保你以空格开头和结尾(或者如果你这样做的话,用逗号替换空格)
同样,最好的选择是在您的数据库中设置多对多关系,但我怀疑您正在寻找一种快速而肮脏的一次性修复。
【讨论】: