点赞功能是目前APP开发的基本功能。今天我们就来说说点赞、评论、收藏等场景的db数据库设计问题。1、我们先来看一下场景。需求:显示点赞数,判断用户是否点赞。它用于重复数据删除。需要判断并显示个人喜欢的列表。一般在用户中心显示文章点赞列表。我们来看看今日头条和微博的例子。今日头条的点赞和微博点赞都是顶级流量,后台一定是复杂的结构。今天我们只谈流行的解决方案。2.1mysql解决方案mysql解决方案,随着nosql的普及,大数据持续火热,但是mysql仍然不可替代,对于大多数中小型项目,数据量在千万级以下,完全可以使用mysql分表+缓存胜任,稳定性是其他解决方案无法比拟的:......star_numint(11)COMMENT'点赞数'}Liketablecreatetablestar{idint(11)NOTNULLAUTO_INCREMENT,post_id,user_id,......}常用查询:查询点赞过文章的用户selectpost_idfromstarwhereuser_id=?查询点赞文章的用户selectuser_idfromstarwherepost_id=?点赞数可以通过定时异步统计更新到post和user表。当数据量不大时,这种设计基本可以满足需求。缺点:数据量大时,查询时一张表的压力很大,需要分表,不管是用post_id还是user_id来hash表。如果有冲突的需求,唯一的办法就是让两张表冗余。这会增加存储空间、维护工作量,并且可能存在一致性问题。2.2Redis解决方案当数据量达到亿级时,就需要经过缓存。因为点赞这个动作非常随机,很多人看到拇指就想点击,所以数据量迅速增加。数据规模增大后,mysql的读写压力很大。这时候就要考虑memcache和redis来做存储或者缓存。为什么一般都选择redis?redis作为流行的nosql,数据类型丰富,可以适应多种场景的需求。使用redis有两个目的,一个是存储,一个是纯缓存,需要+mysql一起。纯缓存是先从mysql往redis中写入数据,用户先读取缓存,miss之后再拉取mysql,同时同步缓存。在cache的大部分场景下,两者是同时使用的,并不冲突。下面说一下redis作为存储的解决方案:场景a:在点赞的地方显示点赞数,只显示点赞数,可以区分用户是否点赞过。一般来说,用户并不关心这个列表。在这种情况下,只需要一个数字。可以的,量比较大的时候一般显示为“7k”和“10W”。以文章id为key//以文章id=888为例127.0.0.1:6379[2]>setstar:tid:888898//设置点赞数OK127.0.0.1:6379[2]>incrstar:tid:888//实现自增个数(整数)899场景b:点赞和去重,避免重复点赞要实现这个需求,必须要有一个文章点赞的uid列表,以uid为key场景c:一般在用户中心,可以看到获取到用户自己的点赞列表的需求,可以使用场景b的数据来实现。用户中心点赞列表场景d:点赞文章列表,类似场景b,以文章id为key//以文章id=888为例127.0.0.1:6379[2]>saddstar:list:tid:888123456789//Likeuidlist(integer)3127.0.0.1:6379[2]>sismemberstar:list:tid:888456//判断是否点赞(integer)1个点赞的地方,如果被点过则显示红色,否则显示为红色会显示黑白,头条上没有地方可以看到点赞列表,但是点击微博可以在详情页看到点赞列表,但是只会显示最近的几十个,没有分页。如下图,我选择了一个热点,就是粉丝多的“猪猪”帖子的点赞榜。可能有人会觉得没有人关心点赞列表,存储会浪费很多资源。最好不要保存!但是,这个数据是必要的一些。两点:重复数据删除。点赞数可以不准确,但去重一定要准确。b.又一个社交产品,用户行为的点点滴滴都需要被记录下来,这对于后续的用户行为分析和数据挖掘是有意义的。上面用string存储的用户点赞数,除了用string存储,也可以用hash存储。文章id分块,每100个存储一个hash,分别存储在hash表中。每篇文章的id是hash的key。该值存储喜欢它的用户id。如果喜欢的用户比较多,为了避免id过多带来的性能问题,可以单独列出来,存储在sortedset结构中。毕竟,只有几个热点。hash方案的优缺点与hash相比:使用较少的全局键,节省内存空间;但是也带来了问题,如何根据文章id路由到对应的hash?它是在散列中还是在集合中查找用户标识?存在不确定性使用hash虽然节省了空间,但增加了复杂性。如何选择取决于个人需求。除此之外,你还有什么其他的方法吗?3、数据一致性当使用redis作为存储时,一定要做好数据的持久化,必须开启rdb和aof,会导致业务只使用一半的机器内存,所以需要做好容量监测及时扩容。另外,只要有数据副本,就会有一致性问题,这是另一个很重要的话题。以后有时间再说吧!写在最后:把题写清楚真的不是一件容易的事。请多多关注并留言,谢谢!前几天写的一篇文章得到了很多同事的热情回复,很荣幸能和很多同事交流!对于工程问题,没有标准的解决方案。一千个人有一千种解决方案。只有你知道哪一款最适合你!期待你更好的想法和方法。
