1
oott123 2021-11-20 10:11:46 +08:00 via Android
还这样,但是只存已读用户,没已读的就当未读
|
2
zpf124 2021-11-20 10:17:41 +08:00
我先说个我之前设计的实现,不一定好,而且当时我们的在线用户量级很小都不担心这个问题。
一张用户表,一张站内信表,一张站内信已读表。 站内信表中有 sendUserId 字段 魔法值 0 代表发送给所有人,其他值代表只发给某人。 因为我们数据量不大,所以消息是直接 join 查的,order 排序未读的展示在前。 |
3
zpf124 2021-11-20 10:23:29 +08:00
本来当时打算有个消息发送组的概念,消息分为发给个人还是发给某个组, 然后组里面有个魔法值是群发。
结果这个功能对于我们本事不是很重要,而且人手要优先干其他的,所以这里就简化了,有给某个组群发的需求,就 foreach ,创建多条信息发送给指定的人。 |
4
zpf124 2021-11-20 10:33:56 +08:00
最后说说你的需求
1 、数据肯定要落库的,虽然这个数据重要性不高丢了就丢了,但发消息偶尔会出现收不到肯定最起码业务领导会不爽。 所以如果想要性能那就用搜索引擎 es 或者其他非关系数据库如 mongoDB ,数据读取层面还可以加 redis 。 2 ,3 、阅读很少那就把阅读单独建表, 就像我们那种, 阅读表包含消息 id 、用户 id 、是否已读、已读时间、创建时间啥的。 |
5
kaiki 2021-11-20 10:41:12 +08:00
@zpf124
群发这块是不是直接发送一个空邮件或只有标题的邮件,邮件数据链接到一个群发表中取邮件内容效率会高点? 感觉发邮件和发文章也没什么太大的区别,就是用户能不能查看而已,既然是给所有人的,当文章来发会不会好一点。 |
6
xiayushengfan OP @zpf124 我是打算是 mongoDB 去重新做这一块。主要 mongoDB 不怎么熟悉。
|
7
xiayushengfan OP |
8
zpf124 2021-11-20 11:38:03 +08:00
@kaiki 最后我们是发多条了,没有组的概念,这种情况下按照你说的方式确实能优化一些存储。
针对后面的问题,我们的文章表有 n 多字段,对于消息来说都是完全没用的,而且文章没有记录多少人已读的。 最后我们的站内信不是用户给用户发送的,基本都是系统通知,"你订阅的 某个资源更新了,url " 类似这种,所以我们和楼主的也不完全相似,因为我们的消息大多数是分组的,个别是全站群发,没有用户间私信。 |
9
zpf124 2021-11-20 11:42:36 +08:00
@xiayushengfan mongodb ,我们用的也不是很有心得,我们还是按照关系型数据库的用法或者 k-v 缓存的用法在用。
比如我们如果用 mongodb 存站内信的话,就是一个集合是所有消息,或者一个集合是一个月的消息之类的维度,每个文档包含文档的全部内容包括所有的接受用户 id ,以及已读状态, 查询的时候 直接查当前用户 id 的文档数据。 |
10
CrazyMonkeyV 2021-11-20 15:25:35 +08:00
这个我以前设计过,我们的情况类似,邮件会分类:
1 、全部用户邮件 先生成一条数据,然后再用户登录的时候,给他发一个邮件。 2 、特定类型用户邮件 先生成一条数据,然后再用户登录的时候,检测是否满足条件,满足给他发一个邮件。 上面这 2 类邮件,还有开始和结束时间(也就是有效期),有效期外登录则不发了 3 、指定用户右键 直接发 这样的话,日活不多的系统,邮件不会太多,mysql 基本没问题 |
11
CrazyMonkeyV 2021-11-20 15:28:17 +08:00
其实主要的概念就是把群发改为了给活跃用户发,减少数据量。
|
12
lesismal 2021-11-20 16:21:35 +08:00 1
### 选型
因为楼主希望不要用 mysql ,所以选择 mongodb ,能支持的数据量足够大,并且 nosql 方便扩展 ### 信件存储方案(按类型分别处理,广播类信件去重) 1. 系统发给用户,多个用户收到的是相同内容:只插入一条到 letter 集合中 2. 系统发给用户,多个用户收到的是不同内容:一个用户一条插入到 letter 集合中,类似用户发给用户 3. 用户发给用户:每个一条插入到 letter 集合中 ### mongodb 集合( collection )和 文档( document )设计 mongodb 的 collection 相当于 mysql 的 table collection 里的 document 相当于 table 的一条数据 collection 设计: 1. collection name: letter document struct: { "_id": xxx, //mongodb 自带的就行 typ: system/p2p/..., time: xxx, from: userid:name, //用户之间的会有这个字段,系统发的看功能设计是否需要 content: xxx, ... } 2. collection name: letter_list document struct: { userid: xxx, letters: [ { id: letter_id_xxx, // 根据信件 id 去 letter 里查 time: xxx, readed: 0, }, ...... ], } 优化:上面的 1 、2 中的 document 是为了方便展示,直接是用展开的结构字段,实际使用中,应该把各个字段合并编码、减少字段数量、从而减少相应的计算消耗和存储空间占用等成本,比如冒号分隔符分割多个字段,取出后 splitN 得到各个字段内容 letter 可以优化成: { "_id": xxx, //mongodb 自带的就行 info: "type:time:from:content", // 例如: "0:1637396101::您的超级 VIP 已经开通!", "1:1637396101:用户 B:您的回复太棒了,非常感谢!" // content 应该放在最后,以面 content 中有冒号时放在中间 splitN 无法正常解析 } letter_list 可以优化成: { "_id": xxx, //mongodb 自带的就行 info: "id:time:readed", // 如:"aaaa:1637396101:0" } ### 其他 具体细节以及 mongo 的一些优化,请根据自己实际情况进行 |
13
xiayushengfan OP @lesismal 谢谢老哥,给的全面了
|