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

未读消息数据库设计问题

  •  
  •   simonlu9 · 70 天前 · 1506 次点击
    这是一个创建于 70 天前的主题,其中的信息可能已经有所发展或是发生改变。

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