数据库 面试题求解~微博数据库设计

michael_roshen · 2014年04月13日 · 最后由 bobby_chen 回复于 2014年11月18日 · 9072 次阅读

假设有一亿个用户,每个用户至少关注 100 个人,如何设计数据库(关系型数据库)满足下面几个需求 1,查找 a 关注了哪些人 2,查找 a 被哪些人关注了 3,查找 a 和 b 共同关注了哪些人

使用 redis, followers 一个 set, followings 一个 set, 可以搜一下微博 CTO 的一个 PPT 有讲。

如果完全使用关系型数据库来解决这个问题,好像很费劲。

#1 楼 @zgm -rd 可惜考的就是关系型数据库,我先看看 redis 的吧,谢谢

#2 楼 @michael_roshen 如果只能这样的话 把 following_id 单独拎出来存,相当于做了一层缓存,但是如果没有关注上限应该也很难 . 避免从至少 1 亿*100 的数据中查. 还要分表分库什么的. 等大神...

好像很有意思,可数据也太大了吧。。

#5 楼 @hooopo 这也太水了吧。。。1 亿啊

用户分表,按某个 hash 方式。 关注与被关注,做序列化的 2 个字段跟着用户分表。 共同关注就直接计算了。

#6 楼 @litblaky @hooopo 的方案的什么问题?我觉得这样很好,够简单! 要查询速度,莫非要用上传说中的“存储过程”,好高深的样子...

这种要是用图数据库才是王道啊。。

@hooopo 的方案挺好的,简单高效,1 亿数据查询并不慢,大家别想多了

#7 楼 @5swords 序列化也有性能问题的吧,有的用户用几千万的粉怎么办?反序列化到内存里再计算不行的吧

#11 楼 @miclle 要关系数据库啊,象这种大V的话,以 1000 粉作为分隔作特殊处理

我觉得在缺少具体情况的方案下没有什么设计的余地 hooopo 那个绝对满足条件 每个用户至少关注 100 个人 那可能这一亿个用户都关注 100 个大 V 具体优化还是要看具体遇到的问题吧

关系数据库设计出来并没有问题,但关系数据库查询所依赖的索引估计和关系表的大小一样,基本上如果过将索引全部装入内存的话,和 redis 相比没有一点优势。

我觉得这个需要做一点冗余 对于每个用户 id 记录关注这个用户的用户 已经用户关注的其他用户分成两个表信息 这样分表的时候不用做 join 直接按 id 取到相应的表就可以获取值了

Instagram 的关注数据结构很简单,不过处理关注的内容推拉的时候确实需要分大小 V 处理。第三个问题,好像没有直接枚举出某些用户共同关注的人的场景,通常是先有了一批人或者一个人,看另外其他的用户都关注了这里面的哪些人,业务场景有很大的区别,导致程序逻辑也不一样。实际使用应该针对不同用户层次的缓存机制 (比如针对频繁登录的用户),纯关系数据库实现感觉压力有点大啊,最起码的使用数据库内建的分区机制是必要的。

@winnie 1 亿?至少 100 亿吧?纯用数据库不是作死吗?

#8 楼 @miclle 是够简单啊,但是 100 亿的数据量,能查出来吗?

#11 楼 @miclle 只要将关注人的 id 序列化,所以要有关注上线,粉丝不需要序列化,需求是找出共同关注,不是共同粉丝。

#19 楼 @zgm 是这样的,可以和用户分表 (xxx) 一样,存在 xxx_funs 的表里。 还要一点假设,关注不可以超 1000。

#19 楼 @zgm 我当然知道只是将 id 序列化而已,我只是觉得序列化的字段不适合用来做频繁的检索

序列化也有性能问题的吧,有的用户用几千万的粉怎么办?反序列化到内存里再计算不行的吧

我的意思是不需要序列化粉丝的 id, 所以不存在 "几千万" 的问题。

常见最简单的分库策略,按用户 id 来做 mod,比如有 5 台数据库服务器,那么用户 id % 5,先计算出该用户落在那台服务器。数据库里的表结构和#5 楼 @hooopo 一样,不过为了反向查找被关注,需要多加一个被关注的表,和关注表是冗余,在关注的时候同时在 2 个表里面插入。

需求 1,2 在单台数据库用单句 sql 查询即可。需求 3,需要 2 次 sql 查询,再在内存中计算。

复杂一些的分库策略,常用注册时间或者用户 ID 区间定义,来保证新加的服务器能够快速分配到新用户。

呵呵~~偶尔看见这个帖子,可不可以使用 nosql 的思想的方式来存呢?比如说 key:A->B value:(B's name) 就表示 A 关注 B

#25 楼 @bobby_chen 有一亿个用户,每个用户至少关注 100 个人,那就得上百亿得数据了,nosql 上百亿的数据查询估计也不行吧,而且题目要求是关系性数据库,so..

#26 楼 @michael_roshen 如果只是存两个用户之间的关系的话,数据量并没有那么大。而且正因为是关系型数据库,所以更不可能所横向的扩展多少列来存某一个用户关注的用户群

需要 登录 后方可回复, 如果你还没有账号请 注册新账号