V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
simonlu9
V2EX  ›  程序员

未读消息数据库设计问题

  •  
  •   simonlu9 · 2022-06-06 16:24:55 +08:00 · 2041 次点击
    这是一个创建于 661 天前的主题,其中的信息可能已经有所发展或是发生改变。

    业务需求是这样,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 这个语句也会建立索引

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

    13 条回复    2022-06-07 16:14:31 +08:00
    zoharSoul
        1
    zoharSoul  
       2022-06-06 16:28:43 +08:00
    你是在提问, 还是在科普?
    npe
        2
    npe  
       2022-06-06 16:30:05 +08:00
    有时候换种思路豁然开朗,即:未读消息大于 1000 时显示 999+
    simonlu9
        3
    simonlu9  
    OP
       2022-06-06 16:30:12 +08:00
    @zoharSoul 就是看看一般是不是这样做,现在采取的是分区方案
    simonlu9
        4
    simonlu9  
    OP
       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
        5
    meta  
       2022-06-06 17:07:42 +08:00
    没看懂你这个是要取得消息还是要取得消息的数量,如果只是要取得数量的话,单独做一个计数器不就行了
    xiaoyangsa
        6
    xiaoyangsa  
       2022-06-06 17:46:49 +08:00
    直接在缓存里做增减嘛。user,type,un_read_count
    或者单独弄个表,内容也是上面那个。免得去拉数据库
    NULL2020
        7
    NULL2020  
       2022-06-06 17:48:47 +08:00
    未读消息 id 存 redis 里,每个用户一份,拉取未读消息数只需要一个 redis 命令,用户拉取消息列表时,清理对应的未读消息
    git00ll
        8
    git00ll  
       2022-06-06 21:57:02 +08:00
    单独为每个用户维护一个 count , 用户点进消息的时候再从数据库查询
    MoYi123
        9
    MoYi123  
       2022-06-07 09:31:16 +08:00
    @simonlu9 这样写性能也会差吗? 试试直接在(userId,type,read_status) 上建索引呢?
    hetal
        10
    hetal  
       2022-06-07 13:57:52 +08:00
    几百万数据就分区了?让我上亿条的无识的人情何以堪
    simonlu9
        11
    simonlu9  
    OP
       2022-06-07 14:29:24 +08:00
    @MoYi123 写应该没什么问题,就是如果系统刚刚好有一个用户是客服,然后很多人都给他发信息,堆积消息未读数有十几万条,基本上扫索引也很慢的,因为 readstatus 就两种状态,基本上索引也要全扫描,后面改成扫描 100 条显示 99+算是个比较偷懒的方法
    simonlu9
        12
    simonlu9  
    OP
       2022-06-07 14:32:16 +08:00
    @meta 一个是获取用户各消息类型的未读消息数,一个是获取各类型的消息列表第一页(按时间倒序),分区的话都要建立这两个索引,代价是索引越来越大
    issakchill
        13
    issakchill  
       2022-06-07 16:14:31 +08:00
    之前做过一个很简易的 im
    未读消息的消息 id 存 redis 拉取未读消息的时候直接 in 这些 ids
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5339 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 05:52 · PVG 13:52 · LAX 22:52 · JFK 01:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.