我考虑过两种类型的用户通知系统。
它们都有一个订阅表,用户可以在其中订阅特定频道
下面的模式用于存储事件的表。
1.昂贵的写作
当新的事情发生时:
|id| |type| |uid| |read| |created|
1 2 2 0 1234
当某个频道出现新情况时,该系统会为订阅该频道的每个用户插入一个新行。
缺点:
- 如果有100万用户订阅了一个频道,则必须为频道中发生的每一件新事情插入100万行
- 浪费空间,如果未正确规范化则重复内容
优点:
- 快速读取时间
- 简单的实现
2.阅读费用高昂
当新的事情发生时:
|id| |type| |created|
1 2 1234
在这个系统中,它只为一个事件插入一行,即它不是特定于用户的。然后,用户读取该表并检查该事件是否发生在他订阅的频道中,然后还比较创建的时间是否大于上次读取的时间。
缺点:
- 阅读成本高昂,因为用户必须进行大量过滤
- 用户特定事件无法轻松处理[例如,回复您的评论]
- 当出现特定于用户的事件时,实现非常复杂
优点:
- 所需空间更少
- 事件的一对一插入,即更少的插入时间
您认为以下情况下哪个更好:
- 这些事件可能在一天内发生5到10次(即写作)
- 每个用户每分钟都会检查(即读取)新事件
我建议使用您的方法组合。
有一个包含消息的表,然后另一个将这些消息的每个用户状态与用户关联的表。例如,您的消息表可能简单到:
- id
- 消息(varchar/text)
你的另一张桌子可能有:
- id
- message_id
- user_id
- 读取(布尔值)
然后,如果您有该用户的任何其他特定信息,您可以在原始消息之外跟踪它。如果更新了原始邮件,它仍然会为所有用户更新。