Ati*_*din 39 mysql database-design data-modeling
我只想弄清楚Facebook的数据库是如何构建用于跟踪通知的.
我不会像Facebook那样复杂化.如果我们想象一个简单的通知表结构:
notifications (id, userid, update, time);
我们可以使用以下方式获取朋友的通知:
SELECT `userid`, `update`, `time`
FROM `notifications`
WHERE `userid` IN
(... query for getting friends...)
Run Code Online (Sandbox Code Playgroud)
但是,应该是什么表结构来检查哪些通知已被读取,哪些没有?
Ati*_*din 40
我不知道这是否是最好的方法,但由于我没有得到任何人的想法,这就是我要做的.我希望这个答案也可以帮助其他人.
我们有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
Run Code Online (Sandbox Code Playgroud)
我们的想法是从通知表中选择通知并加入notificationsRead表并检查上次读取的通知和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...
))
Run Code Online (Sandbox Code Playgroud)
不检查上面的查询.感谢@espais的db设计理念
你可以添加另一个表...
tblUserNotificationStatus
-------------------------
- id (pk)
- notification_id
- user_id
- read_status (boolean)
Run Code Online (Sandbox Code Playgroud)
如果您想保留历史记录,可以保留X最新通知,并删除比列表中最后一个通知旧的剩余通知....
如果在您发出通知时,您提供了当时可用的所有相关通知,则可以通过将时间戳附加到可通知事件并跟踪每个用户上次收到通知的时间来简化此操作.但是,如果您处于多服务器环境中,则必须注意同步.请注意,此方法不需要真正的日期时间戳,只需要单调增加.
我发现这里没有人解决这样一个事实:通知通常会重复出现。即将进行的交易的通知始终是相同的,但其中包含不同的交易 ID 或日期。像这样:{您有一笔新的即将付款:@ paymentID,到期日为@ dueDate }。将文本放在不同的表中也可以帮助
因此,我还为这些抽象通知制作了一个表格,这些抽象通知只是在用户下链接到一个中间表,其中一种通知类型可以多次发送给一个用户。我还不是通过外键 ID 将通知链接到用户,但我为所有通知创建了通知代码,并为这些代码的 varchar 字段建立了 full_text 索引,以提高读取速度。由于这些通知需要在特定时间发送,因此开发者编写起来也更容易
NotificationService::sendNew( Notification::NOTE_NEW_PAYMENT, ['paymentId'] => 123, ['dueDate'] => Carbon::now(), 'userIdToSendTo' );
Run Code Online (Sandbox Code Playgroud)
现在,由于我的消息中将包含自定义数据,这些数据将插入到字符串中,正如您事先从第二个参数中看到的那样,然后我会将它们存储在数据库 blob 中。像这样
$values = base64_encode(serialize($valuesInTextArray));
Run Code Online (Sandbox Code Playgroud)
这是因为我想将通知与其他表解耦,因此我不想在通知表之间建立不必要的 FK 关系,这样我就可以说通知 234 附加到事务 23,然后加入并获取该关系交易ID。将其解耦可以消除管理这些关系的开销。缺点是,几乎不可能删除通知,例如删除交易时,但在我的用例中,我决定,无论如何都不需要这样做。
我将在App端检索并填充文本,如下所示。诗。我正在使用某人的 vksprintf 函数(https://github.com/washingtonpost/datawrapper/blob/master/lib/utils/vksprintf.php),支持他!
$valuesToFillInString = unserialize(base64_decode($notification->values));
vksprintf( $notificationText->text, $valuesToFillInString )
Run Code Online (Sandbox Code Playgroud)
另请注意我索引了哪些字段,因为我将按它们查找或排序
我的数据库设计如下
================================
================================
[ClusterIndex] => (user_id, 创建日期时间)
================================
| 归档时间: |
|
| 查看次数: |
25381 次 |
| 最近记录: |