web-dev-qa-db-fra.com

Facebook comme le suivi des notifications (DB Design)

J'essaie simplement de déterminer comment la base de données de Facebook est structurée pour suivre les notifications de suivi.

Je ne vais pas aller beaucoup dans la complexité comme Facebook est. Si nous imaginons une simple structure de table pour les notifitionnons:

notifications (id, userid, update, time);

Nous pouvons obtenir les notifications d'amis en utilisant:

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

Cependant, quelle devrait être la structure de la table pour vérifier quelles notifications ont été lues et qui ne l'ont pas fait?

41

Je ne sais pas si c'est la meilleure façon de le faire, mais depuis que je n'ai eu aucune idée de quelqu'un d'autre, c'est ce que je faisais. J'espère que cette réponse pourrait également aider les autres aussi.

Nous avons 2 tables

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

L'idée est de sélectionner des notifications à partir de la table de notifications et de rejoindre la table des notificationsDead et de vérifier la dernière notification de lecture et des lignes avec ID> notificationID. Et chaque fois que la page de notifications est ouverte, mettez à jour la ligne de la table de notificationsRead.

La requête pour les notifications non lisées, je suppose que c'était comme ça ..

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...
))

La requête ci-dessus n'est pas cochée. Merci à l'idée de la conception de DB de @espais

40

Vous pourriez ajouter une autre table ...

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

Si vous souhaitez conserver une histoire, vous pouvez conserver les dernières notifications et supprimer le reste plus ancien que votre dernière notification de la liste ....

9
the_e

Je ne vois personne ici aborde le fait que les notifications sont généralement réintroductions, aka. La notification d'une prochaine transaction sera toujours la même, mais avec une carte de transaction différente ou une date de transaction. Comme: {Vous avez un nouveau paiement à venir: @PayMentaid, avec une date d'échéance de @ducedate}. Avoir des textes dans une table différente peut également aider avec

  1. Si vous souhaitez modifier le texte de notification plus tard sur
  2. Rendre l'application multilingue est plus facile, car je ne peux que calmer la table de notifications avec un code de langue et récupérer la chaîne appropriée

Ainsi, j'ai également fait une table pour ces notifications abstraites, qui sont simplement liées sous l'utilisateur avec une table centrale, où un type de notification peut être envoyé à un utilisateur à plusieurs reprises. J'ai également lié les notifications à l'utilisateur non par un identifiant de clé étranger, mais j'ai effectué des codes de notification pour toutes les notifications et Full_text indexé le champ Varchark de ces codes, pour des vitesses de lecture plus rapides. En raison du fait que ces notifications doivent être envoyées à des moments spécifiques, il est également plus facile pour le développeur d'écrire

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

Maintenant que mes messages vont avoir des données personnalisées dans elles, cela est inséré dans la chaîne, comme vous pouvez le constater à partir du deuxième argument à l'avance, je les stockerai dans une blob de la base de données. En tant que tel

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

C'est parce que je veux découpler les notifications des autres tables et, en tant que tel, je ne veux pas de croire des relations fk chenessécaires et à la table des notifications, de sorte que je puisse par exemple dire que la notification 234 est attachée à la transaction 23, puis rejoindre et obtenez-y identifiant de transaction. Découplage Cela élimine les frais généraux de gérer ces relations. L'inconvénient est qu'il est presque impossible de supprimer des notifications, quand par exemple une transaction est supprimée, mais dans mon cas d'utilisation, j'ai décidé, cela n'est pas nécessaire de toute façon.

Je récupérerai et remplira les textes du côté de l'application comme suit. Ps. J'utilise la fonction VKSPRINTF de quelqu'un (- https://github.com/washingtonpost/datawrapper/blob/master/lib/utils/vksprintf.php ), les accessoires à lui!

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

Notez également quels champs je l'indice, car je vais trouver ou trier par eux

Ma conception de base de données est la suivante

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

Tableau: Utilisateurs

  • id (pk)

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

Tableau: Notifications

  • id (pk)
  • user_id (fk, indexé)
  • tEXT_ID (FK - Notification Table)
  • valeurs (blob) [contenant la gamme de valeurs, pour entrer dans la chaîne de texte]
  • createdDateTime (DateTime)
  • lire (booléen)

[Clusterindex] => (user_id, crééeDateTetime)

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

Tableau: Tableaux de notification

  • id (pk)
  • text_id (Uniquem indexé)
  • texte (Varchar) [{Vous avez un nouveau paiement à venir: @PayMentaid, avec une date d'échéance de @ducedate}]
  • remarque (varchar, nullable) [Notes pour les développeurs, colonne d'information]
3
Karl Johan Vallner

Table suit

tilisateur

  • userid (entier)
  • nom complet (Varchar)

Notification

  • notificationID (entier)
  • créationDate (date)
  • notificationDetailurl (Varchar)
  • isread (Bolenan)
  • description (Varchar)
  • userid (f.k)