今日头条、微博 timeline 中的是否收藏、点赞、关注数据库应该怎么设计?

2018-08-23 18:46:03 +08:00
 kaxi

拉一页的动态,假如 20 条数据出来。每条动态上需要点亮是否关注、收藏、点赞这些状态。请问应该怎么去设计数据库比较合理?

我目前是在关系型数据库中通过下面的方式实现的,但是感觉性能上有缺陷。 如果用 nosql 的方式,又存在点赞人数非常多比如极端几十万个用户点赞,这种问题。 麻烦大佬指点一下!

//关注状态
if($needFollow){
$in = trim(implode(',', array_unique($uid_follow)),',');
$res = $this->query("SELECT `uid_follower` FROM relationship WHERE uid_follower in (".$in.")");
foreach ($res as $v){
$ufArr[$v['uid_follower']] = 1;
}
}
//点赞状态            
$in = trim(implode(',', array_unique($feedid_uid)),',');
$res = $this->query("SELECT `feedid_liker` FROM feed_like WHERE feedid_liker in (".$in.")");
foreach ($res as $v){
$fuArr[$v['feedid_liker']] = 1;
}
//收藏状态            
$in = trim(implode(',', array_unique($feedid_uid)),',');
$res = $this->query("SELECT `feedid_uid` FROM collect WHERE feedid_uid in (".$in.")");
foreach ($res as $v){
$cfuArr[$v['feedid_uid']] = 1;
}
2992 次点击
所在节点    数据库
16 条回复
kaxi
2018-08-23 18:51:14 +08:00
我考虑将上面三种状态的查询通过异步执行的方式去执行。性能应该会有所提高。但是感觉还是治标不治本。

感觉还是需要在数据库层面去想办法才行。

望高人指点
jininij
2018-08-23 19:09:22 +08:00
经常有一条微博被点十万加的赞。但很少有人给十万条微博点赞。所以优先肯定是以用户来分组。
每篇微博的 id,用一个 8 字节的长整数,点十万个赞也就 80k 的数据。客户端 down 到本地来,逐条处理都可以。
只是提供一种思路。
kaxi
2018-08-23 19:19:43 +08:00
@jininij 好像你这种方案还是没解决需要多路查询的问题,或者我没理解到位? 我想如果用 nosql 的方案每条动态里都记录点赞、收藏的用户 id 这样就可以不用查询别的表就能判断点赞、收藏状态了。但存在的问题是当点赞、收藏用户量很大的话那么对应的动态记录数据量就会异常大了。如果用关系型数据库,有需要每次都去查询多张表。
yuanfnadi
2018-08-23 21:27:56 +08:00
@kaxi 有一个史上最大的 redis 集群。
kaxi
2018-08-23 21:28:52 +08:00
help
kaxi
2018-08-23 21:31:14 +08:00
@yuanfnadi 求细说,现在主要是这种状态关系用什么方案得到最佳
sy20030260
2018-08-23 21:54:03 +08:00
这种有实时性需求的场景,存储自然会使用到 Redis 或者其他的 NoSQL,只用 MySQL 之类的数据库单机性能在这种场景肯定是不足的,除此之外一般还需要做:
1.使用 MQ 做异步解耦
2.数据冷热分离,热数据冷却下沉至 SSD 或硬盘
sy20030260
2018-08-23 21:58:49 +08:00
而且点赞关注这种消息流服务是一个完整的后台服务模块,单单考虑存储设计是不足以解决所有问题的,消息旁路,消息防丢,服务降级...是个大的系统问题
howryan
2018-08-23 22:05:13 +08:00
mark
liprais
2018-08-23 22:06:19 +08:00
你注意看就知道微博那个对于热点大部分时候是不准的
kaxi
2018-08-23 22:08:42 +08:00
@sy20030260 感谢提醒。如果将三种关系表都存到缓存其实性能瓶颈就基本消失了,其实三种状态查询就是简单 key-value
kaxi
2018-08-23 22:09:18 +08:00
@liprais 是的,包括抖音
liubai
2018-08-23 22:59:11 +08:00
建议使用 KV 存储,如 Redis、HBase 等,实际上这种 Feed 流系统可以直接抛弃关系型数据库,全部使用 KV 解决。当然数据量少的情况,可以用下关系型数据库。
之前做过一个分享 https://myslide.cn/slides/9250,希望能有所帮助。
kaxi
2018-08-23 23:31:10 +08:00
@liubai 嗯 多谢
teek
2018-08-23 23:39:39 +08:00
关系型其实可以作为系统最后的一个存储地方,前面加缓存,比如 redis 这种,redis 重点可以用那些批量的操作,减少网络 io 的耗时,用好批量,在我系统下有 100 倍的提升。
owenliang
2018-08-24 08:58:34 +08:00
微博被点赞是微博的属性,你是否点赞是你的属性,两码事吧

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

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

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

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

© 2021 V2EX