如何使用mysql实现消息通知_mysql消息表设计实战

1次阅读

mysql消息通知系统需聚焦查未读快、标已读稳、按时间准三大目标;核心表含id、receiver_id、type、content、is_read、created_at等字段,并建(receiver_id,is_read,created_at)和(receiver_id,created_at)联合索引,群发与单发应分表处理。

如何使用mysql实现消息通知_mysql消息表设计实战

用 MySQL 实现消息通知系统,关键不在字段,而在理清业务路径和查询重心。核心是让“查未读”快、“标已读”稳、“按时间看最新”准——这三点决定了表结构和索引怎么搭。

消息表必须包含的字段

一张轻量但可扩展的通知表,至少要有这些字段:

  • id:BIGint 自增主键,避免 INT 溢出,适配千万级用户场景;
  • receiver_id:接收者用户 ID,非空,用于 WHERE receiver_id = ? 查询;
  • sender_id(可选):记录来源,私信或互动类通知需要;
  • type:TINYINT 类型,如 1=系统公告、2=评论提醒、3=点赞通知,方便分类筛选;
  • content:VARCHAR(2048) 足够存短文本;富文本或长内容建议抽离到关联表;
  • is_read:TINYINT(1),0 表示未读,1 表示已读,支持 count(*) WHERE is_read = 0 快速统计;
  • created_attimestamp default CURRENT_TIMESTAMP,精确到秒,自动写入,时区友好;
  • updated_at:TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,记录状态变更时间(比如标记已读)。

必须加的联合索引

没有索引,查未读、分页、按类型过滤都会变慢。重点建这两个:

  • (receiver_id, is_read, created_at):覆盖最常用查询,例如「查某用户所有未读消息,按时间倒序」;
  • (receiver_id, created_at):支撑「拉取最新 20 条」或「分页加载历史消息」;

注意:不要只对 receiver_id 单独建索引——MySQL 在范围查询(如 is_read = 0)后无法高效利用后续字段,联合顺序很关键。

区分单发与群发,用两张表更清晰

系统公告、活动推送这类群发消息,和点对点私信逻辑不同,混在一张表里容易拖慢查询、增加冗余。推荐拆开:

  • mass_messages:存群发模板,字段含 title、content、status(草稿/已发)、publish_time;
  • user_notifications:存每个用户实际收到的记录,含 user_id、mass_msg_id、is_read、receive_time;

发送时用 INSERT … select 批量写入:
INSERT INTO user_notifications (user_id, mass_msg_id, is_read, receive_time)
SELECT id, 123, 0, NOW() FROM users WHERE status = ‘active’;

时间处理别忽略时区和精度

TIMESTAMP 是首选,不是因为“看起来新”,而是它原生支持:

  • 自动转时区:写入时按连接时区转为 UTC 存储,查询时再转回本地,用户看到的时间一致;
  • 空间省:4 字节 vs DATETIME 的 5–8 字节;
  • 微秒支持(如需更高精度):用 TIMESTAMP(6),但多数通知场景秒级足够。

避免用 INT 存时间戳——丢失时区语义,且无法直接用 DATE()、HOUR() 等函数做时间维度分析。

text=ZqhQzanResources