根据 tag 找用户,怎么设计数据库会比较好呢

2015-01-16 20:35:35 +08:00
 fffonion

每个用户有数量不定的tag,比如长得帅,没朋友等;tag的数量可能随时会增加
需求是想找出所有有没朋友的tag的用户,或者可能想找所有同时有长得帅和没朋友tag的用户,应该怎么设计数据库呢?

目前想到的两种:
第一种是按tag存,每个tag下存有这个tag的用户的id的列表,有用户添加标签之后就去追加这个列表(这样是不是比较适合用mongodb?)
第二种是存一个表,字段是用户id和用户tag,每个用户的每个tag就存一条记录,然后给tag字段加索引,然后select fileid from table where tag = 想查询的tag;

大家觉得哪种更有优势,或者有更好的设计方法呢?

2021 次点击
所在节点    数据库
34 条回复
puncsky
2015-01-17 03:38:05 +08:00
更正:这里我们应该着重于对“读”优化。 关键的地方出现了口误。。。 )逃
plantain
2015-01-17 07:35:15 +08:00
用户和Tag多对多啊
zjmdp
2015-01-17 08:10:02 +08:00
基于lucene的solr,也就是搜索引擎那套原理,对tag->用户建立反向索引
semicircle21
2015-01-17 11:52:02 +08:00
@zjmdp solr 支持 tag 的组合吗?
(我猜是支持的, 就是想确认一下)
semicircle21
2015-01-17 12:27:19 +08:00
@zjmdp 我看了 solr 的 start guide, 确实是支持 组合 的, 但 reference 好长.. 感谢先.
zjmdp
2015-01-17 12:58:10 +08:00
@semicircle21 我最近刚在做这一块,对按tag筛选用户包(导出千万用户,用户规模在1亿左右),你这块对并发有要求么?
felixzhu
2015-01-17 12:58:54 +08:00
就用mongo,在用户表里面存一个tags就可以的,对tags做索引
semicircle21
2015-01-17 14:28:48 +08:00
@zjmdp 这个技术选型也和规模并发有关?
目前我没这个需求, 以前遇到这个问题时, 我发现关系型数据库处理不好, 也不是关键场景, 然后就自己用 go 配合 redis 写了一套基于反查原理的, 规模不大, 支持了组合检索, 和一些 tag 间的逻辑, 当时找了很久的轮子, 没有发现 solr 这个.
你目前使用 solr 有什么体会?
zjmdp
2015-01-17 17:36:59 +08:00
@semicircle21 数据迁移,schema调整都比较麻烦,系统比较复杂(各种参数调整),估计你要用的话需要折腾一阵子,本身通过tomcat之类的容器提供http服务,并发量应该也就这么回事
gongweixin
2015-01-17 19:09:35 +08:00
第一种是按tag存,每个tag下存有这个tag的用户的id的列表,有用户添加标签之后就去追加这个列表(这样是不是比较适合用mongodb?) 这个是什么意思?
是两列,一列tag, 一列所有用户的id的字符串,类似用(,)号分割构成一个串
还是 1 + n列,一列tag, n个用户n列?

我们现在是用的第二种,然后缓存到了redis中。量不大的话有索引直接查库性能也不会太差。
fffonion
2015-01-18 00:24:36 +08:00
@gongweixin 是两列,但是用nosql去存;第二种的话感觉不太……优雅 ?www

@puncsky @plantain 同意,确实是要userIdsByTags和tagsByUserIds这样子,因为目前需求只是按tag找用户,所以就把tagsByUserIds省略了


@zjmdp 查了一下solr,那个是像sphinx一类的东西吧,好像比较复杂,先mark着看有没轻量的解决方案
memeda
2015-01-19 02:29:07 +08:00
redis sadd
gongweixin
2015-01-23 14:11:59 +08:00
第一种方法基本可不取,一个tag有10W用户的话基本没法存取更新,但反过来可以,因为一个用户只会有几个tag, 再加上方法2,需要考虑性能的话,可以把查出来的数据缓存起来。这样正反查询都可以了。如果tag可修改的话就保存tag的id,因为你还要查询同时拥有多个tag的用户,方法1也实现不了这个需求。
gongweixin
2015-01-23 14:14:02 +08:00
如果用solr会更简单一点,只要存用户和用户拥有的tags就行了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/162827

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX