tags的数据库设计问题

2012-12-08 22:58:42 +08:00
 talentsnail
每个topic有几个tags,每个tag也能对应多个topic,应该如何设计数据库最合理呢?

想到的一种解决办法是三张表:
1.topic (topic_id,tags)多个tags用某个特殊符号分隔
2.tag (tag_id,tag)
3.topic_tag (topic_id,tag_id)

但是觉得效率会很低,大家的解决方案是怎样?
6779 次点击
所在节点    MySQL
50 条回复
zhfsxtx
2012-12-13 00:39:47 +08:00
怎么没人帮我讲下 mongodb 该 怎么弄呢,额啊
talentsnail
2012-12-14 22:16:48 +08:00
@gfreezy
@lqs
@ElmerZhang
@BigZ
@lookhi
@lusin
@sobigfish
@Mutoo
@atom
@isy
@zhangtao
@AntiGameZ
@napoleonu
@88250
@yupbank
@xjay
@huxos
谢谢大家,大家的讨论对我很有启发,部分感谢已经送出:)
paloalto
2012-12-14 22:26:44 +08:00
我也是这么做的,只不过topic表里只存了一个记录tag数量的字段tag_num
其他的两张表一个放tag_id和tag_name
一个放tag_id和top_id
gfreezy
2012-12-14 22:31:53 +08:00
怎么设计关系真心不大,反证流量高了怎么设计都是要靠缓存来抗的。
与其各种为了性能做的hack,还不如把表结构做的清晰,然后通过缓存来解决性能问题。
@napoleonu 缓存list,不是直接缓存对象,是缓存一个id的list。然后每个model只会被缓存一次,取的时候根据id list,用get_multi,一次性获得一个list的对象。
lookhi
2012-12-14 22:37:55 +08:00
@ElmerZhang 因为还有站内搜索
xjay
2012-12-15 02:21:33 +08:00
@gfreezy 流量高对系统架构要求更高,什么缓存,什么cdn,都不可信,一旦缓存命中不到,或者cdn抽风,你的系统是不是随时准备挂掉了?表结构清晰是好,但是如果数据量过大,单表查询问题不大,链表的话,很耗时的。如果topic的tag量不大可以直接保存到topic表,那就是相当于数据库端的缓存,一旦你前端缓存命中不到的时候,后端缓存还可以用的上。而many2many的结构也需要,主要是用来做备份,一旦tag缓存字段出问题了,那么这个many2many还可以用得上,可以用来恢复数据等。
napoleonu
2012-12-15 09:57:41 +08:00
@gfreezy id list哪里来的?数据库读?
nojt7Zm
2012-12-15 10:26:30 +08:00
标记下
napoleonu
2012-12-15 10:51:19 +08:00
@gfreezy

如果用上覆盖索引(index1(last_reply_time,topicid),index2(post_time,topicid),index3(tagid,topicid))之后再通过get_multi获得列表详细确实比走覆盖索引再join一下topic 表或者再回表获得详细信息效率高很多,mysql数据量大之后join的效果不是那么理想。多谢指导,获益匪浅。

这是建立在从cache拿数据比直接从数据库拿数据效率高,没有测试,实际上也不一定,别的不说,直接从数据库join拿,只需要一次网络IO,而从数据库拿到再去cache获得详细得两次网络IO。当然当数据量很大并且越来越大,随着join性能越来越低的时候走cache的效率会越高,水平切分的分布式系统就更不用说了。

还有一点我想说的是,即使是 stackoverflow.com 这种全球排名百名内的站点,这么多年来也就400万topic的数据,大网站并没有想象的那么多。百万量级甚至千万量级的数据规模下,LZ这种设计可以说一点问题都没有,特别是在内存廉价和SSD出现后,facebook数据库服务器标配内存不都128G还是256G了么。

从楼上的各个回答来看,使用或者赞同这种设计的人不在少数。退一万步讲,冗余下tags对于生成cache也是有好处的,而业务复杂度和空间上损失的代价也不是那么高,当然如果cache用的好看起来必要性似乎也没那么高,但肯定称不上幼稚的设计。
sectic
2014-07-04 16:43:55 +08:00
我们用redis搞了这个问题。 tag -> entity , entity -> tag 有点浪费

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

https://tanronggui.xyz/t/54442

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

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

© 2021 V2EX