未读消息数据库设计问题

2022-06-06 16:24:55 +08:00
 simonlu9

业务需求是这样,app 应用是有点赞,评论,at 我 评论 消息 现在用户量上来了,以前这些消息都存一个表 ( id,user_id,type (消息类型),subject_id(类型),readStatus(阅读状态))

现在有差不多七百多万消息,每个人读取自己的未读消息数量 性能会下降,只能建立索引去 count idx(type,readStatus,user_id),目前做了 mysql 分区,按用户 hash 到 20 个分区上面,二级索引文件比较大

还有每个用户消息列表要拉取第一页消息 select * from message where user_id = :userId and type=:type order by create_time desc 这个语句也会建立索引

分表的话要还是要建立索引,不知道大家项目是不是这样做,还有发现分区和分表建立二级索引最大的区别是分区是在几百万数据建立索引,而分表是每个表都要建一个索引

2084 次点击
所在节点    程序员
13 条回复
zoharSoul
2022-06-06 16:28:43 +08:00
你是在提问, 还是在科普?
npe
2022-06-06 16:30:05 +08:00
有时候换种思路豁然开朗,即:未读消息大于 1000 时显示 999+
simonlu9
2022-06-06 16:30:12 +08:00
@zoharSoul 就是看看一般是不是这样做,现在采取的是分区方案
simonlu9
2022-06-06 16:31:42 +08:00
@npe 也做了这个优化,select count(1) from (select 1 from sys_message_user where user_id = :userId and `type` = :type and read_status = :readStatus limit 100 ) t
meta
2022-06-06 17:07:42 +08:00
没看懂你这个是要取得消息还是要取得消息的数量,如果只是要取得数量的话,单独做一个计数器不就行了
xiaoyangsa
2022-06-06 17:46:49 +08:00
直接在缓存里做增减嘛。user,type,un_read_count
或者单独弄个表,内容也是上面那个。免得去拉数据库
NULL2020
2022-06-06 17:48:47 +08:00
未读消息 id 存 redis 里,每个用户一份,拉取未读消息数只需要一个 redis 命令,用户拉取消息列表时,清理对应的未读消息
git00ll
2022-06-06 21:57:02 +08:00
单独为每个用户维护一个 count , 用户点进消息的时候再从数据库查询
MoYi123
2022-06-07 09:31:16 +08:00
@simonlu9 这样写性能也会差吗? 试试直接在(userId,type,read_status) 上建索引呢?
hetal
2022-06-07 13:57:52 +08:00
几百万数据就分区了?让我上亿条的无识的人情何以堪
simonlu9
2022-06-07 14:29:24 +08:00
@MoYi123 写应该没什么问题,就是如果系统刚刚好有一个用户是客服,然后很多人都给他发信息,堆积消息未读数有十几万条,基本上扫索引也很慢的,因为 readstatus 就两种状态,基本上索引也要全扫描,后面改成扫描 100 条显示 99+算是个比较偷懒的方法
simonlu9
2022-06-07 14:32:16 +08:00
@meta 一个是获取用户各消息类型的未读消息数,一个是获取各类型的消息列表第一页(按时间倒序),分区的话都要建立这两个索引,代价是索引越来越大
issakchill
2022-06-07 16:14:31 +08:00
之前做过一个很简易的 im
未读消息的消息 id 存 redis 拉取未读消息的时候直接 in 这些 ids

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/857622

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX