站内信通知数据表设计

需求

管理员可以全平台用户发送站内信,针对活跃用户才能收到消息,僵尸用户不需要收到消息,也可以给单个用户发送。

分析

从上诉需求可以分析出,我们可以抽象出有信息实体,消息实体用来存放具体的消息内容,比如标题、内容、消息发送时间。在其次用户需要读取数据那么我们需要和用户有联系,那么如何联系呢?首先得有用户实体吧。读取消息没有具体得用户肯定不行。有了用户那么我们就得关联了吧。那么我们就会想到关联表存放消息和用户之间得关联,大致有用户、消息、阅读状态等等。

思考

如果系统管理员发一个通知所有用户的站内信,我们给每个用户插入一条信息一样的数据,分析可行性行,用户少完全可以接受也不会存在性能和空间浪费,那么你的做法可能是组装好一个批量插入的SQL进行插入,这样就保证,每个用户都会存在一份站内信了。如果单独给一个用户发送消息,那么就插入一条。如果用户量大呢,比如20万用户,那么你会向数据库插入20万条信息,单用户就一条。那么会造成空间浪费,且不说你怎么去实现,一次性插入20万条数据?需要多久时间应该心里清楚吧。那么如果不这样做,我们怎么去实现。如数据库只用保存一条站内信是否可行,那么怎么样才能通知到每个用户呢?之前我们主动给每个用户插入数据,思考如果我们让用户主动来拿是否可以减少空间上的浪费呢?主动来拿是什么意思?当用户比如请求站内信接口我们给他关联上站内信就行了。避免非活跃用户也给他们进行插入数据,减少资源的浪费。只要是活跃用户主动来拿那么在给他进行插入数据即可。

数据表

messages

CREATE TABLE `messages` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '消息标题',
  `content` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '消息内容',
  `sender` int(10) unsigned NOT NULL COMMENT '发送者',
  `sender_role` char(191) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '发送者角色',
  `receiver` int(10) unsigned NOT NULL COMMENT '接受者:0-通知所有用户、其他数字通知单用户',
  `type` char(191) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '消息类型:system-系统消息 order-订单消息',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `messages_receiver_index` (`receiver`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

user_messages

CREATE TABLE `user_messages` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL COMMENT '用户id',
  `message_id` int(10) unsigned NOT NULL COMMENT '消息id',
  `read_status` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '阅读状态:0-未读 1-已读',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `user_messages_user_id_index` (`user_id`),
  KEY `user_messages_message_id_index` (`message_id`)
) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

messages 数据表主要存在消息相关信息,如下:
在这里插入图片描述

receiver为0表示通知所有用户,那么当前有用户来取,会在user_messages里面插入一条数据,如图:
在这里插入图片描述
可能有人会问,我怎么知道用户拿了到那条了,首先user_messages里面有一条数据是message_id你可以排序拿你最后一次拿到的系统消息id,然后在去messages里面获取未拿取的站内信,这样就做到共用一条站内信了,防止

疑问

有人可能会问,如果用户1年未登录,那么存在很多未读站内信怎么办?比如2000条,为例,如果用户取主动拉取插入数据会不会影响服务器呢。我们可以这样去解决,按照分页的方式优先拿取最时间最早的前30条,一次插入30条不过分吧,后面在依次拿每页未读的数据,也就是分批拉取。还可以在运营角度取考虑,如果该用户注册时间小于站内信的时间我们不进行拉取。

如果我们做成APP接口去,那么GET请求里面既要做查询和插入操作,这样不符合GET的定义。如果并发请求会造成重复插入,那么你可以使用联合唯一索引做限制 user_id,message_id,或者使用锁机制,比如文件锁,Redis锁这些来防止并发读写,具体问题具体取分析。

其实还可以对接口进行职责拆分,单独两个接口,一个接口去拉取消息入库,一个接口获取消息列表,这样就会更清晰。

感谢大大们的阅读。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值