基于mongodb用户评论系统数据结构设计

简述

以微信朋友圈为例,但又与微信不同是微信是以强社交为主,只有好友之间才可以查阅对方的朋友圈内容,而我们当前的设计类似的微博以弱社交的表现形式,其显著特点就是即便互相没有关注也可以访问对方的朋友圈数据。所以设计之初首先要确认应用场景是强社交,还是弱社交关系。

场景

基于timeline的用户留言与点赞

信息流

注意事项,AREA1,AREA2分别是两块SCHEMA分别存储在mongodb中,本文的重点也是根据实际示例探讨这两块SCHEMA的存储结构。

1. 系统所有的时间均是timestamp long类型,时间间隔24小时之内均显示(xx小时之前),如1小时27分钟前则显示(1小时前);间隔1小时内则显示(xx分钟前);不足1分钟则显示(刚刚)。该时间算法由客户端自己完成,服务器端只提供创建时间,默认时区为UTC+8.
2. 用户显示上报设备型号,则显示该记录。有可能用户上包的设备型号是(oneplus a6000)则显示为(一加 6,或者 oneplus 6)所以设备型号要后台维护。
3.点赞,延迟3秒与服务器同步,可取消点赞。点赞成功图标高亮显示,不影响数据同步。无人点赞数字区域显示
4.留言总数,无人留言显示回复
5.默认值显示3-5条最新的留言记录。支持emoji字符存储。点击45则进入留言详细列表

留言列表

注意事项,分页显示数据,处理好同步机制。
A.同1
B.同3
C.这条记录用于张三回复了李四
D.王五的这条留言被2人点赞其中含当前用户,则高亮显示点赞图标。但无人回复
E.钱七回复了麻六,则麻六的回复标签上有回复记录的总数。
F.回复主贴

键盘由点击具体事件后弹出,如先点击1,A,输入框提示回复主体。

评论

1.直接评论主贴

回复

A.回复他人留言

存储方案

写入效率低,数据允余占用存储空间,读取效率高。

基于redis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
new post:
{post category}:{author id}:{post id}
朋友圈:123:67890
uid为123的用户发布朋友圈该条记录id为67890

new reply:
{post category}:{author id}:{post id}:reply:{uid}:{reply post id}
朋友圈:123:67890:reply:852:741052
uid为852的用户回复‘uid为123的用户发布朋友圈id为67890'。该条记录id为741052

new reply @ user:
{post category}:{uid}:{postid}:replyto:{uid}:to:{uid}:{replyto post id}
朋友圈:123:67890:replyto:852:to:963:7895412
uid为852的用户回复uid为963的用户,在‘uid为123的用户发布朋友圈id为67890'记录下。该条记录id为7895412

new like base one post:
like:{post id}:{uid}:{like id} 点赞
like:67890:915:731564
uid为915的用户点赞了postid为67890的文章,该条记录id为731564

更多操作

获取uid为123的所发朋友圈所有内容
朋友圈:123:*

获取朋友圈文章id为264832的所有点赞记录
like:264832:*

获取朋友圈文章id为264832的所有回复记录
朋友圈:*:264832:reply* (含用户间的回复)
朋友圈:*:264832:reply:* (不含用户间的回复)
朋友圈:*:264832:replyto:* (仅含用户间的回复)

获取UID为123朋友圈文章id为264832的所有回复记录
朋友圈:123:264832:reply* (含用户间的回复)
朋友圈:123:264832:reply:* (不含用户间的回复)
朋友圈:123:264832:replyto:* (仅含用户间的回复)

key-value
AREA 1
article:{uid}:{postid} 发布动态

AREA 2
article:{uid}:{postid}:reply:{uid}:{postid} 回复主题帖
article:{uid}:{postid}:replyto:{uid}:to:{uid}:{postid} 在这个主题帖下面回复某人

基于postid点赞
like:{postid}:{uid}:{likeid} 点赞

基于mongodb

示例详解

服务器返回数据

API的设计原则是尽可能的将能一次返回所需要的所有数据,从而减少与服务器间的交互。而我们在存储的时候也不太可能将动态数据直接存储持久化。一旦数据结构改变变动会比较大,从而适当的设计关联关系有助于简化业务逻辑充分的利用mongodb高性能特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
{
"category":"PICTURE",
"content":"这是一个带9张图片的动态",
"createtime":1543374370935,
"id":90012,
"likeCount":3,
"commentCount":9,
"device":"红米 6",
"geo":null,
"author":{
"headImg":"http://cdnhost/headimg/91d192886a5b9f3e14b6ffa1a674b55d.jpg",
"nickName":"王五",
"uid":10003
},
"pictureUrls":[
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d11.jpg",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d12.jpg",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d13.jpg",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d14.jpg",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d15.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d16.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d17.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d18.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d19.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d10.png"
],
"comments":[
{
"author":{
"headImg":"http://cdnhost/headimg/5fdd5874ff6d571e6d0abac9660ec81f.jpg",
"nickName":"麻子",
"uid":10004
},
"commentCount":0,
"content":"这是一个回复678ijnfdsf",
"createtime":1543374600935,
"id":500013,
"likeCount":0,
"postId":90012
},
{
"author":{
"headImg":"http://cdnhost/headimg/5fdd5874ff6d571e6d0abac9660ec81f.jpg",
"nickName":"麻子",
"uid":10004
},
"commentCount":0,
"content":"这是一个回复678ijnfdsf",
"createtime":1543374500935,
"id":500012,
"likeCount":0,
"postId":90012
},
{
"author":{
"headImg":"http://cdnhost/headimg/01f8cc1938c30b28b1e80d256faddd84.jpg",
"nickName":"听他们说玩游戏名字起得不能太长",
"uid":10005
},
"commentCount":0,
"content":"这是一个回复678ijnfdsf",
"createtime":1543374700935,
"id":500011,
"likeCount":0,
"postId":90012
}
],
"likes":[
{
"createTime":1543375480935,
"id":882211,
"postId":90012,
"user":{
"headImg":"http://cdnhost/headimg/e1ea32968eb094232f74b712017e5d14.jpg",
"nickName":"李四",
"uid":10002
}
},
{
"createTime":1543375590935,
"id":882212,
"postId":90012,
"user":{
"headImg":"http://cdnhost/headimg/5fdd5874ff6d571e6d0abac9660ec81f.jpg",
"nickName":"麻子",
"uid":10004
}
},
{
"createTime":1543375700935,
"id":882214,
"postId":90012,
"user":{
"headImg":"http://cdnhost/headimg/5fdd5874ff6d571e6d0abac9660ec81f.jpg",
"nickName":"麻子",
"uid":10004
}
}
]
}

AREA1 模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
"category":"PICTURE",
"content":"这是一个带9张图片的动态",
"createtime":1543374370935,
"id":90012,
"likeCount":3,
"commentCount":9,
"device":"红米 6",
"geo":null,
"author":{
"headImg":"http://cdnhost/headimg/91d192886a5b9f3e14b6ffa1a674b55d.jpg",
"nickName":"王五",
"uid":10003
},
"pictureUrls":[
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d11.jpg",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d12.jpg",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d13.jpg",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d14.jpg",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d15.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d16.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d17.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d18.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d19.png",
"http://cdnhost/pic/e1ea32968eb094232f74b712017e5d10.png"
],
...

AREA2 comments 模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
"comments":[
{
"author":{
"headImg":"http://cdnhost/headimg/5fdd5874ff6d571e6d0abac9660ec81f.jpg",
"nickName":"麻子",
"uid":10004
},
"commentCount":0,
"content":"这是一个回复678ijnfdsf",
"createtime":1543374600935,
"id":500013,
"likeCount":0,
"postId":90012
},
{
"author":{
"headImg":"http://cdnhost/headimg/5fdd5874ff6d571e6d0abac9660ec81f.jpg",
"nickName":"麻子",
"uid":10004
},
"commentCount":0,
"content":"这是一个回复678ijnfdsf",
"createtime":1543374500935,
"id":500012,
"likeCount":0,
"postId":90012
},
{
"author":{
"headImg":"http://cdnhost/headimg/01f8cc1938c30b28b1e80d256faddd84.jpg",
"nickName":"听他们说玩游戏名字起得不能太长",
"uid":10005
},
"commentCount":0,
"content":"这是一个回复678ijnfdsf",
"createtime":1543374700935,
"id":500011,
"likeCount":0,
"postId":90012
}
...
]

AREA2 comments 模块存储优化

1
2
3
4
5
6
"comments_postid":[
500013,
500012,
500011,
...
]

AREA2 likes 模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
"likes":[
{
"createTime":1543375480935,
"id":882211,
"postId":90012,
"user":{
"headImg":"http://cdnhost/headimg/e1ea32968eb094232f74b712017e5d14.jpg",
"nickName":"李四",
"uid":10002
}
},
{
"createTime":1543375590935,
"id":882212,
"postId":90012,
"user":{
"headImg":"http://cdnhost/headimg/5fdd5874ff6d571e6d0abac9660ec81f.jpg",
"nickName":"麻子",
"uid":10004
}
},
{
"createTime":1543375700935,
"id":882214,
"postId":90012,
"user":{
"headImg":"http://cdnhost/headimg/5fdd5874ff6d571e6d0abac9660ec81f.jpg",
"nickName":"麻子",
"uid":10004
}
}
...
]

AREA2 likes 模块存储优化

1
2
3
4
5
6
"likes_postid":[
882211,
882212,
882214,
...
]

最终的储存结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"category":"PICTURE",
"content":"这是一个带9张图片的动态",
"createtime":1543374370935,
"id":90012,
"likeCount":3,
"commentCount":9,
"device":"红米 6",
"geo":null,
"author_uid":10003,
"comments_postid":[
500013,
500012,
500011,
...
],
"likes_postid":[
882211,
882212,
882214,
...
]
}

update

2018.11.29
补充一下。likeCount commentCount 是实时计算的出来的,而不是持久化在mongodb中。

Fred范方青 wechat
项目合作请联系我私人微信: fredtv23
0%