仅从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位是时间,所以是可以排序的,其顺序就是时间顺序。
点赞的问题可以通过类似的方式实现,就留给你自己思考了。
5 回答3.2k 阅读✓ 已解决
3 回答3.6k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
1 回答2.4k 阅读✓ 已解决
1 回答2.3k 阅读✓ 已解决
5 回答1.4k 阅读
3 回答1.2k 阅读✓ 已解决
效率低? MySQL 毕竟是个久经考验的数据库,它没你想得那么脆弱。
再一个,讨论问题要考虑场景:
以上仅是个人想法,有错误还请指正 :)