要根据具体情况来实现,如果数据库很小用你的第一种方法就可以满足了如果数据量很大我是考虑用冗余来换取查询效率 表结构基本如下,欢迎讨论:create table article ( id int, tag varchar(255) primary id )create table tag ( id int, tag varchar(10), cnt int, primary id )create table tag_relate ( tag_id int, article_id int, primary tag_id, article_id )
今天继续讨论,昨天走的太急了,也许么说清楚,我是这样做的 先有tag_id=1的,对应tag名是风景,在tag表中查询风景的纪录(完全匹配),得到tag_id和用户id,然后再在文章表中查询, SQL: select * from article where tag_id like '%[tag_id]%'and user_id='user_id' 我注不同的是tag_id入库和tag表多个字段:用户ID;
SQL: select * from article where tag_id like '%[tag_id]%'and user_id='user_id' ------------------------------------------------------------------------------- 这样肯定不行啊,like '%**%'是不能使用索引的
当查找某一个TAG的相应文章时,我是用循环根据TAGID找到对应的TAG名,然后进行整个TAG表的查询,找出同一类别的文章。
跟LZ不同的是,我TAG表加了个用户ID
文章表:
文章ID
用户ID
tag_ID//这里记录TAG表的ID,用逗号隔开,比如:1,2,3,
.
.
.
.
tag表:
tag_ID
用户ID
tag名称
.
.
.
---------------------------------------------------------------------------
能否贴出SQL和explain结果?谢谢!
表结构基本如下,欢迎讨论:create table article
(
id int,
tag varchar(255)
primary id
)create table tag
(
id int,
tag varchar(10),
cnt int,
primary id
)create table tag_relate
(
tag_id int,
article_id int,
primary tag_id, article_id
)
请注意我的tag_id的入库方式([1],[2],[3],),如果要找风景相关文章,得到[1],在文章表中查询tag_id为[1]的即可(其实只需要模糊查询)。就可以得到所有的相关文章。依次循环,可以得到{风景,朋友,老师,}的文章。
http://www.qiyesucha.com
我的做法是: article表
id,
title,---标题之类的
tag varchar(200)直接把中文存进去,比如"美女,mm,K歌", 搜索的时候就方便多了.
其实这问题是考虑用户需求,通常我的做法就是上面那种,网上常见的结果也是搜索的时候,是连tag字段也一起搜(方法是否一样就不知道了).tag在article表中直接存放实际的内容就行了,将来可能还有其它附加功能要考虑.
------------------------------------------------------------------
能否详细的说一下采用哪种“搜索”方式?效率如何?
先有tag_id=1的,对应tag名是风景,在tag表中查询风景的纪录(完全匹配),得到tag_id和用户id,然后再在文章表中查询,
SQL: select * from article where tag_id like '%[tag_id]%'and user_id='user_id'
我注不同的是tag_id入库和tag表多个字段:用户ID;
而且如果将来需求有改动时,方法2要灵活得多,更容易作修改。
-------------------------------------------------------------------------------
这样肯定不行啊,like '%**%'是不能使用索引的
2.这也是一个“无级分类”的问题,tag本身就是分类
ps:“无级分类”不等于“无限级分类”!!
3.tag和文章都是变化的,不能永久固定两者的relationship
4.tag < article(字串长度)很显然,除非一早就把tag指定,否则难免在文章增加的时候会出现新的tag
也就是上面3所讲的问题我倾向是方法1增加字段
$article["tags"]=array(1,3,5,7……);
$tag["article"]=array(17653,12468……);
因为查询是双向的,所以两个表都应该有"relationship"在文章入库的时候,更新tag表,把article_id增加到相关tag的记录里面
增加新的tag的时候也做一次全article表的更新(涉及的文章)没必要用“1文章对1tag的做一个记录”方式(1文章含n个tag=n个记录)php的数组函数处理功能很强大的,结合位运算(包括sql的位运算)查询很方便的web查询一般都是使用limit,输出只是几十至上百条数据,所以,没必要考滤一次全部查出
反而应该考虑组合多次查询优化最终查询的SQL语句更好
这个个人觉得和桌面程序是很大区别的
------------------------------------
按tag搜索文章的时候,SQL怎样写?$tag["article"]=array(17653,12468……);
------------------------------------------
如果一个tag非常热门,引用次数达万次以上,那这个字段检索起来应该就很慢了
tag table
tag:value
"PHP":17653,12468……
"WEB2.0":17653,19472,20356……
(必要时可以加入字段——文章标题,思路要换一下)搜索"PHP"得到17653,12468……(只有一条记录啊),然后交给php数组函数处理,获得每篇文章的id,然后进行二次搜索另外,你不是打算把上万个文章的标题都列在同一个html吧?
所以二次搜索最多只是数百条而已虽然两次或多次搜索,但中间限定的条件很明确,搜索的记录数量也不大
比起用一条sql全部搜索出来要好得多
发表点愚见...
没做过大项目...
不知道这样到底有多大影响...
不过我想ls的方法可以cache各个tag的数目来满足效率...
设置个更新cache的机制(定时,手动随便)应该没问题...