网易云音乐的评论回帖是怎么存的?
网易云音乐" title="网易云音乐">网易云音乐的评论回帖是怎么存的?关系性数据库还是给非关系性数据库,又或者是两者同时使用?一首歌的回帖就30多万了,感觉用关系性数据库的话,效率很低?求大神解答
回答:
效率低? MySQL 毕竟是个久经考验的数据库,它没你想得那么脆弱。
再一个,讨论问题要考虑场景:
- 是不是所有歌曲都有几十万的评论量?
- 网易云音乐歌曲的 评论 看起来只有 赞数 这个字段会在记录生成后被修改,这意味着大多数时间它都是只读的,因此对于热门评论可以做热缓放在前面抗压。
- 并不是一次性拉取几十万条评论到客户端,如前面所说,热评可以放热缓分压,客户端方面即使拉取不那么热的评论,也可以一次十条/百条去拉。
- 其实这种大量只读的情况下,热缓做得好,命中率高的话,数据库方面本身就不会承受特别多的压力。
以上仅是个人想法,有错误还请指正 :)
回答:
仅从MongoDB的角度说明这种东西可以怎么存。至于别人到底是怎么存,我们是不知道的。
关系模型存法
不多介绍,可以按照范式设计成跟关系数据库一样的表结构来存储,大概是:
{ _id: ObjectId(...),
comment: "...",
time: ISODate(...),
user: "...",
musicId: "...",
...
}
如果用惯关系数据库的用户,这样的做法简单自然。在现在讨论的场景下,这样没有太大的问题,在数据量大时可以使用分片来达到水平扩展以应对数据量的增长。
不过仍有可以改进的地方。这要从MongoDB的模型设计来讲起。简单地说,MongoDB是实用主义,怎么方便怎么来,怎么快怎么来,完全不应该受范式的约束。但这也意味着你的模型要从应用的需求出发。仅从上面截图的信息,可能有2个不同的需求:
- 评论
- 点赞
考虑到评论和点赞都有可能上万甚至上十万百万,它们以单独的集合来存放会比较合适。但是为了读取和存储效率,我会考虑把多条评论压缩到一起,这种方式通常称为分桶(bucket)。
非关系模型存法
{ _id: ObjectId(...),
musicId: "...",
// 根据需要可能将音乐本身的一些数据冗余进来
musicName: "...",
comments: [
{content: "...", time: ISODate(...), user: "..."},
{content: "...", time: ISODate(...), user: "..."},
{content: "...", time: ISODate(...), user: "..."},
...
],
count: 10, // 该桶内已有10条comments
}
comments的数据量我会考虑一页会展示多少评论(比如30条),那么在添加评论时可以有:
db.comments.updateOne({ musicId: "...",
count: {$lt: 30}
}, {
$push: {
comments: {content: "...", time: ISODate(...), user: "..."}
},
$inc: { count: 1 }
}, {
upsert: true
});
// 优化查询速度会使用到索引:
db.comments.createIndex({
musicId: 1,
count: 1
});
在查询时总是只需要最多取最新的2条记录就可以查到第一页:
db.comments.find({ musicId: "..."
}).sort({_id: -1}).limit(2)
// 这个查询需要索引
db.comments.createIndex({
musicId: 1,
_id: -1
});
注意_id的高4位是时间,所以是可以排序的,其顺序就是时间顺序。
点赞的问题可以通过类似的方式实现,就留给你自己思考了。
以上是 网易云音乐的评论回帖是怎么存的? 的全部内容, 来源链接: utcz.com/p/196666.html