Facebook的通知跟踪(DBdevise)

我只是想弄清楚Facebook的数据库是如何构build跟踪通知。

我不会像Facebook那样复杂。 如果我们想象一个简单的通知表结构:

notifications (id, userid, update, time);

我们可以使用以下方式获取朋友的通知:

 SELECT `userid`, `update`, `time` FROM `notifications` WHERE `userid` IN (... query for getting friends...) 

但是,表结构应该检查哪些通知已被读取,哪些没有被读取?

我不知道这是否是这样做的最好方法,但是因为我没有任何人的想法,所以我会这样做。 我希望这个答案也可以帮助其他人。

我们有2张桌子

 notification ----------------- id (pk) userid notification_type (for complexity like notifications for pictures, videos, apps etc.) notification time notificationsRead -------------------- id (pk) (i dont think this field is required, anyways) lasttime_read userid 

这个想法是从通知表中select通知,并joinnotificationsRead表,并检查最后阅读通知和ID> notificationid行。 并且每次打开通知页面时都会更新notificationsRead表中的行。

未读通知的查询我想会是这样的..

 SELECT `userid`, `notification`, `time` from `notifications` `notificationsRead` WHERE `notifications`.`userid` IN ( ... query to get a list of friends ...) AND (`notifications`.`time` > ( SELECT `notificationsRead`.`lasttime_read` FROM `notificationsRead` WHERE `notificationsRead`.`userid` = ...$userid... )) 

上面的查询不被检查。 感谢@espais的dbdevise理念

你可以添加另一个表…

 tblUserNotificationStatus ------------------------- - id (pk) - notification_id - user_id - read_status (boolean) 

如果您想保留历史logging,则可以保留X个最新通知,并删除比列表中最后一个通知更早的其他通知。

如果当您提供通知时,您可以提供当时可用的所有相关通知,则可以通过将时间戳附加到可通知事件来更简单,并跟踪每个用户上次收到通知的时间。 但是,如果您处于多服务器环境中,则必须小心同步。 请注意,这种方法不需要真正的date时间戳,只是单调增加的东西。

我看到没有人在这里解决这个事实,通知通常是重新发生,又名。 即将到来的交易的通知将总是相同的,但具有不同的交易ID或date。 因此:{你有一个新的即将到来的付款:@paymentID,截止date为@dueDate}。 有不同的表中的文本也可以帮助

  1. 如果您想稍后更改通知文字
  2. 使应用程序多语言更容易,因为我可以将通知表与语言代码分层并检索适当的string

因此,我也为那些抽象通知做了一个表格,这些通知只是在用户的中间表下链接,一个通知types可以多次发送给一个用户。 我还将通知链接到用户,而不是外键ID,但是我为所有通知和全文索引了这些代码的varchar字段的通知代码,以获得更快的读取速度。 由于这些通知需要在特定的时间发送,所以开发人员也更容易编写

 NotificationService::sendNew( Notification::NOTE_NEW_PAYMENT, ['paymentId'] => 123, ['dueDate'] => Carbon::now(), 'userIdToSendTo' ); 

现在,因为我的消息中会有自定义的数据,所以它会被插入到string中,正如您从第二个参数中可以看到的那样,然后我将它们存储在数据库blob中。 因此

 $values = base64_encode(serialize($valuesInTextArray)); 

这是因为我想解耦来自其他表的通知,因此我不想从通知表中删除不安全的FK关系,以便我可以例如说通知234被附加到事务23,然后join并得到交易ID。 解耦这消除了pipe理这些关系的开销。 缺点是,删除通知时几乎不可能,例如删除了一个事务,但在我的用例中,我决定,这是不需要的。

我将按照以下方式检索和填充应用程序端的文本。 PS。 我用的是vksprintf函数( https://github.com/washingtonpost/datawrapper/blob/master/lib/utils/vksprintf.php ),道具给他!

 $valuesToFillInString = unserialize(base64_decode($notification->values)); vksprintf( $notificationText->text, $valuesToFillInString ) 

还要注意我索引哪些字段,因为我要去查找或sorting

我的数据库devise如下

==============================

表:用户

  • id(pk)

==============================

表格:通知

  • id(pk)
  • user_id(fk,索引)
  • text_id(fk – NotificationTexts表)
  • 值(blob)[包含值的数组,input到文本string中]
  • createdDateTime(DateTime)
  • 读(布尔)

[ClusterIndex] =>(user_id,createdDateTime)

==============================

表格:NotificationTexts

  • id(pk)
  • text_id(uniquem索引)
  • text(varchar)[{您有一个即将到来的新付款:@paymentID,截止date为@dueDate}]
  • note(varchar,nullable)[开发人员注意事项,信息栏]

表格如下

用户

  • userId(整数)
  • 全名(VARCHAR)

通知

  • notificationId(整数)
  • creationDate(Date)
  • notificationDetailUrl(VarChar)
  • isRead(bollean)
  • 描述(VarChar)
  • userId(FK)